在Web开发中,经常需要对图片上传、下载或预览。Kratos一套轻量级Go微服务框架,本文将介绍在Kratos中要如何实现。
接着我们将以Kratos初始化的项目(kratos new helloworld -r https://gitee.com/go-kratos/kratos-layout.git
)为基点,进行修改,详细如下:
- 通过http请求form-data的方式,上传图片并保存
- 通过http请求下载、预览图片
1. 修改Service:上传、下载和预览
1.1 上传:
go
package service
import (
"context"
transporthttp "github.com/go-kratos/kratos/v2/transport/http"
v1 "helloworld/api/helloworld/v1"
"helloworld/internal/biz"
"io"
"os"
)
// 上传
func (s *GreeterService) Upload(ctx transporthttp.Context) (err error) {
file, header, err := ctx.Request().FormFile("file")
if err != nil {
return
}
defer file.Close()
// 修改文件名并创建保存图片
imageFile, err := os.Create("./band_" + header.Filename)
if err != nil {
return
}
defer imageFile.Close()
// 将文件内容复制到保存的文件中
_, err = io.Copy(imageFile, file)
if err != nil {
return
}
return nil
}
上例中,我们通过ctx.Request().FormFile
获取文件,通过os.Create将文件的名称修改为band_
+ w文件名,最后io.Copy将文件内容复制到保存的文件中。
1.2 下载:
go
func (s *GreeterService) Download(ctx transporthttp.Context) error {
imageFile, err := os.Open("./go.png")
if err != nil {
return err
}
defer imageFile.Close()
payload, err := io.ReadAll(imageFile)
if err != nil {
return err
}
// 设置HTTP响应头
// 打开为预览
//ctx.Response().Header().Set("Content-Type", "image/png")
// 打开为下载
ctx.Response().Header().Set("Content-Type", "application/octet-stream")
ctx.Response().Header().Set("Content-Disposition", "attachment; filename=go2.png")
// 将结果写入
_, err = ctx.Response().Write(payload)
return err
}
上例中,我们通过设置了Header
的不同Content-Type
来分别实现是预览或者下载。 其中
-
application/octet-stream
,通知浏览器以二进制流的形式下载文件。 -
Content-Disposition
,其中attachment
表示将文件作为附件下载,filename=download.png
指定了下载文件的名称。
2. 注册路由
go
package server
import (
v1 "helloworld/api/helloworld/v1"
"helloworld/internal/conf"
"helloworld/internal/service"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/transport/http"
)
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, greeter *service.GreeterService, logger log.Logger) *http.Server {
var opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
),
}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
srv := http.NewServer(opts...)
v1.RegisterGreeterHTTPServer(srv, greeter)
//路由注册
route := srv.Route("/")
//图片上传
route.POST("/upload", greeter.Upload)
//图片下载
route.GET("/download", greeter.Download)
return srv
}
测试1. 上传
- 启动Kratos HelloWorld Http 服务
js
> msg=[HTTP] server listening on: [::]:8001
- 我们通过http服务localhost:8001, 路由/upload,上传本地图片
heibao.jpg
,curl如下
cmd
curl --location 'http://localhost:8001/upload?file=null' \
--form 'file=@"/D:/heibao.jpg"'
在工作目录下,多出了一个band_heibao.jpg
的文件,说明上传并图片成功。尝试打开图片
正常显示。
测试2: 下载、预览
在GeeteeingService.Download的代码,通过修改http.Header设置来实现预览
go
ctx.Response().Header().Set("Content-Type", "image/png")
打开浏览器,输入http://localhost:8001/download
,显示如下:
如果修改为
go
//ctx.Response().Header().Set("Content-Type", "image/png")
ctx.Response().Header().Set("Content-Type", "application/octet-stream")
ctx.Response().Header().Set("Content-Disposition", "attachment; filename=go2.png")
则为浏览器下载