简介
本文接着上文(Golang GinWeb框架-快速入门/参数解析)继续探索GinWeb框架
上传文件
单文件上传
注意: 文件名必须是安全可信赖的, 需要去掉路径信息,保留文件名即可
- package main
- import (
- "fmt"
- "github.com/gin-gonic/gin"
- "log"
- "net/http"
- "os"
- )
- func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- // 设置请求表单最大内存限制,默认是30MB
- //内部调用http请求的ParseMultipartForm方法,该方法要求传入一个字节数, 要取MultipartForm字段的数据,先使用ParseMultipartForm()方法解析Form,解析时会读取所有数据,但需要指定保存在内存中的最大字节数,剩余的字节数会保存在临时磁盘文件中
- maxMultipartMemory := int64(8 << 20)
- log.Printf("解析文件到内存的最大字节:%d", maxMultipartMemory)
- router.MaxMultipartMemory = maxMultipartMemory // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // single file
- file, _ := c.FormFile("file") //FormFile从表单中返回第一个匹配到的文件对象(结构)
- log.Printf("获取到的文件名:%s", file.Filename) //文件名必须是安全可信耐的,需要去掉路径信息,保留文件名即可
- // Upload the file to specific dst.
- currentPath, _ := os.Getwd() //获取当前文件路径
- dst := currentPath + "/" + file.Filename
- log.Printf("保存文件绝对路径:%s", dst)
- c.SaveUploadedFile(file, dst)
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
- }
- //模拟单文件上传:
- //curl -X POST http://localhost:8080/upload -H "Content-Type: multipart/form-data" -F "file=@文件名"
多文件上传, 详情参考(https://github.com/gin-gonic/examples/blob/master/upload-file/multiple/main.go)
- package main
- import (
- "fmt"
- "github.com/gin-gonic/gin"
- "log"
- "net/http"
- "os"
- )
- func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- // 设置请求表单最大内存限制,默认是30MB
- //内部调用http请求的ParseMultipartForm方法,该方法要求传入一个字节数, 要取MultipartForm字段的数据,先使用ParseMultipartForm()方法解析Form,解析时会读取所有数据,但需要指定保存在内存中的最大字节数,剩余的字节数会保存在临时磁盘文件中
- maxMultipartMemory := int64(8 << 20)
- log.Printf("解析文件到内存的最大字节:%d", maxMultipartMemory)
- router.MaxMultipartMemory = maxMultipartMemory // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Upload the file to specific dst.
- currentPath, _ := os.Getwd() //获取当前文件路径
- // Multipart form
- form, _ := c.MultipartForm() //多文件表单
- files := form.File["upload[]"] //通过前端提供的键名获取文件数组
- for _, file := range files {
- dst := currentPath + "/" + file.Filename
- log.Printf("保存文件绝对路径:%s", dst)
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
- }
- //模拟多文件上传
- //curl -X POST http://localhost:8080/upload -H "Content-Type: multipart/form-data" -F "upload[]=@文件1" -F "upload[]=@文件2"
路由分组
路由分组可用于新老接口兼容, 针对不同分组的路由使用不同的中间件处理逻辑等
- func main() {
- router := gin.Default()
- // Simple group: v1 路由分组1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
- // Simple group: v2 路由分组2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
- router.Run(":8080")
- }
中间件
我们可以用下面的两种方式初始化Gin引擎
- r := gin.New() //得到一个不使用任何中间件的Gin引擎Engine对象r
- // Default With the Logger and Recovery middleware already attached
- // 默认方法使用Logger(日志记录器)和Recovery(异常自恢复)中间件
- r := gin.Default()
自定义程序崩溃后的处理方式(邮件,微信,短信等告警)
- package main
- import (
- "fmt"
- "github.com/gin-gonic/gin"
- "log"
- "net/http"
- )
- func CustomRecovery() gin.HandlerFunc {
- return func(c *gin.Context) {
- defer func() {
- //if r := recover(); r != nil {
- // log.Printf("崩溃信息:%s", r)
- //}
- if err, ok := recover().(string); ok {
- log.Printf("您可以在这里完成告警任务,邮件,微信等告警")
- c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
- }
- c.AbortWithStatus(http.StatusInternalServerError)
- }()
- c.Next()
- }
- }
- func main() {
- // Creates a router without any middleware by default
- r := gin.New()
- // Global middleware
- // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
- // Recovery middleware recovers from any panics and writes a 500 if there was one.
- //r.Use(CustomRecovery()) //使用自定义中间件处理程序崩溃
- //使用匿名函数组成中间件,处理程序崩溃
- r.Use(func( c *gin.Context){
- defer func() {
- if err, ok := recover().(string); ok {
- log.Printf("您可以在这里完成告警任务,邮件,微信等告警")
- c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
- }
- c.AbortWithStatus(http.StatusInternalServerError)
- }()
- c.Next()
- })
- r.GET("/panic", func(c *gin.Context) {
- // panic with a string -- the custom middleware could save this to a database or report it to the user
- panic("程序崩溃")
- })
- r.GET("/", func(c *gin.Context) {
- c.String(http.StatusOK, "ohai")
- })
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
- }
- //模拟程序崩溃: curl http://localhost:8080/panic
参考文档
Gin官方仓库:https://github.com/gin-gonic/gin