简介
本文接着上文(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