Kratos: http上传、下载和预览图片

在Web开发中,经常需要对图片上传、下载或预览。Kratos一套轻量级Go微服务框架,本文将介绍在Kratos中要如何实现。

接着我们将以Kratos初始化的项目(kratos new helloworld -r https://gitee.com/go-kratos/kratos-layout.git)为基点,进行修改,详细如下:

  1. 通过http请求form-data的方式,上传图片并保存
  2. 通过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. 上传

  1. 启动Kratos HelloWorld Http 服务
js 复制代码
> msg=[HTTP] server listening on: [::]:8001
  1. 我们通过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")

则为浏览器下载

参考

相关推荐
StevenSurpass29 分钟前
打印业务彻底解耦:FastPrintAgent 统一 JSON 模型 + FastReport 引擎的设计与落地
mqtt·http·中间件·打印·fastreport
liyinchi19882 小时前
微信小程序支付遇到“由于小程序违规,支付功能暂时无法使用” 解决办法
java·微信小程序·go
天天喝旺仔4 小时前
Go 泛型实战:从类型参数、约束到可复用泛型容器与函数
数据结构·算法·容器·go
gospace1 天前
【无标题】
go·gb28181·gowvp
小此方1 天前
Linux网络(十二):HTTP短连接与长连接:从Connection机制到Cookie、Session,彻底理解HTTP的无状态
服务器·网络·http
我不会起名字3221 天前
一天一道算法题(35):电话号码的字母组合
java·数据结构·后端·python·leetcode·go·回溯
江畔柳前堤1 天前
On-Policy Distillation 全景深潜
人工智能·网络协议·目标检测·http·机器学习·chatgpt·重构
江湖十年1 天前
Go GOPROXY 兜底链的坑:从一次诡异的 CI lint 失败说起
后端·面试·go
157092511342 天前
Android进阶之光:HTTP协议原理深度解析
android·网络协议·http
秋风点枝2 天前
gogogo!go语言感悟大观--打卡day01
go·devops