Golang Gin 中间件
一.中间件
1 package main 2 3 import ( 4 "fmt" 5 "gin01/middlewares" 6 "text/template" 7 "time" 8 9 "github.com/gin-gonic/gin" 10 ) 11 12 /*** 13 中间件的注意事项: 14 1. gin.Default()默认使用了Logger和Recover中间件,其中: 15 Logger 中间件将日志写入gin.DefaultWriter,即使配置了GIN_MODE=release. 16 Recover 中间件会recover任何panic.如果没有panic的话,会写入500响应. 17 如果不详使用上面两个默认中间件,可以使用gin.New()新建一个没有任何默认中间件的路由. 18 19 2. gin中间件中使用goroutine 20 当在中间件或handler中启动新的goroutine时,不能使用原始上下文(c *gin.Context), 必须使用副本(c.Copy()) 21 22 ***/ 23 24 func UnixToTime(timestamp int) (result string, err error) { 25 fmt.Println(timestamp) 26 t := time.Unix(int64(timestamp), 0) 27 return t.Format("2006-01-02 15:04:05"), nil 28 29 } 30 31 func initMiddleware(c *gin.Context) { 32 fmt.Println("我是中间件start") 33 start := time.Now().UnixMicro() 34 c.Set("username", "name") // 在中间件中设置的数据, 35 username := c.GetString("username") // 可以在其他中间件中获取到 36 fmt.Println(username) 37 if true { // 这里如果没有调用到c.Next()的话就会按照原来的顺序执行 38 c.Next() // 主动在控制函数中调用剩下的所有控制函数 39 c.Abort() // 终止该请求的剩余控制处理函数 40 } 41 42 // 当有耗时任务执行,并不影响返回响应的时候,不能直接将(c *gin.Context)在goroutine中使用 43 cCp := c.Copy() 44 go func() { 45 time.Sleep(time.Second * 2) 46 fmt.Println("Done! in path", cCp.Request.URL.Path) 47 }() 48 49 end := time.Now().UnixMicro() 50 fmt.Println("我是中间件end,耗时:", end-start) 51 } 52 53 func GlobMiddlewareOne(c *gin.Context) { 54 fmt.Println("我是全局中间件:GlobMiddlewareOne") 55 } 56 57 func GlobMiddlewareTwo(c *gin.Context) { 58 fmt.Println("我是全局中间件:GlobMiddlewareTwo") 59 } 60 61 func main() { 62 router := gin.Default() 63 router.SetFuncMap(template.FuncMap{ 64 "UnixToTime": UnixToTime, 65 }) 66 67 // 配置全局中间件 68 router.Use(GlobMiddlewareOne, GlobMiddlewareTwo) 69 70 router.LoadHTMLGlob("templates/**/*") 71 72 router.Static("/static", "./static") 73 74 // 中间件: GET/POST/PUT/DELETE 第一个参数是路由路径,第二个参数开始可以传多个func(*Context)控制函数, 75 // 收到请求后会依次按顺序执行, 你也可以c.Next()主动在控制函数中调用剩下的所有函数 76 router.GET("/", middlewares.InitMiddleware, initMiddleware, func(c *gin.Context) { 77 fmt.Println("我是首页") 78 c.String(200, "我是首页") 79 }, func(c *gin.Context) { 80 fmt.Println("我是第三个控制函数") 81 c.String(200, "我是第三个控制函数") 82 }) 83 84 // 路由分组中间件 85 // 分组中间件的设置一 86 // adminRouters := r.Group("/admin", xxx) 87 // 分组中间件的设置二 88 // adminRouters.Use(xxx) 89 90 router.Run("0.0.0.0:8080") 91 92 } 93 94 /*** 95 // 分组路由中间件的配置 96 func AdminRouters(r *gin.Engine) { 97 98 adminRouters := r.Group("/admin") 99 // 分组中间件的设置一 100 // adminRouters := r.Group("/admin", xxx) 101 // 分组中间件的设置二 102 // adminRouters.Use(xxx) 103 { 104 // http://localhost:8080/admin/ 105 adminRouters.GET("/", func(c *gin.Context) { 106 c.String(http.StatusOK, "后台首页") 107 }) 108 109 // 通过控制器去控制路由更方便,因为控制器可以继承 110 // http://localhost:8080/admin/user 111 adminRouters.GET("/user", admin.UserControl{}.Index) 112 113 // http://localhost:8080/admin/user/add 114 adminRouters.GET("/user/add", admin.UserControl{}.Add) 115 116 // http://localhost:8080/admin/user/edit 117 adminRouters.GET("/user/edit", admin.UserControl{}.Edit) 118 119 // http://localhost:8080/admin/article 120 adminRouters.GET("/article", admin.ArticleControl{}.Index) 121 } 122 } 123 ***/
二.文件上传
1 // 文件上传步骤: 2 // 3 // 1. HTML Form表单必须要指定:enctype="multipart/form-data" 属性 4 // 2. Form表单指定<input type="file" name="face" /> 5 // 3. 多文件上传的话就是多个"<input type="file" name="face[]" />" ,但是name属性值一致 6 func (con UserControl) DoAdd(c *gin.Context) { 7 // 单文件 8 file, _ := c.FormFile("face") 9 // 上传文件至指定目录 10 dst := model.GetSaveImagePathName(file.Filename) 11 err := c.SaveUploadedFile(file, dst) 12 13 // 多文件 14 form, _ := c.MultipartForm() 15 files := form.File["face1[]"] 16 for _, file := range files { 17 dst := model.GetSaveImagePathName(file.Filename) 18 c.SaveUploadedFile(file, dst) 19 20 } 21 if err == nil { 22 username := c.PostForm("username") 23 password := c.PostForm("password") 24 c.JSON(http.StatusOK, gin.H{ 25 "username": username, 26 "password": password, 27 "filename": dst, 28 }) 29 } else { 30 31 c.String(http.StatusBadRequest, "%s uplaod err %s!", file.Filename, err.Error()) 32 } 33 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?