经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
gin中间件&控制器&model
来源:cnblogs  作者:木子七  时间:2024/2/28 9:12:08  对本文有异议

中间件

Gin 框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等。

通俗的讲:中间件就是匹配路由前和匹配路由完成后执行的一系列操作

路由中间件

Gin 中的中间件必须是一个 gin.HandlerFunc 类型,配置路由的时候可以传递多个 func 回调函数,最后一个 func 回调函数前面触发的方法都可以称为中间件

  1. // 请求方式的源码参数,... 可以传入多个func(context *gin.Context)
  2. // 可以在func(context *gin.Context)之前传入自定义的一些处理方法
  3. relativePath string, handlers ...HandlerFunc)
定义和使用路由中间件
写法一
  1. // 定义一个中间件要执行的方法
  2. func MiddlewareFunc() {
  3. fmt.Println("中间件方法")
  4. }
  5. func ApiRoutersInit(router *gin.Engine) {
  6. apiRouter := router.Group("api")
  7. {
  8. apiRouter.GET("list",
  9. func(context *gin.Context) {
  10. // 请求前执行中间件方法
  11. MiddlewareFunc()
  12. },
  13. // 执行请求
  14. func(context *gin.Context) {
  15. context.String(http.StatusOK, "ok")
  16. })
  17. }
  18. }
写法二
  1. // 定义一个中间件要执行的方法
  2. func MiddlewareFunc(context *gin.Context) {
  3. fmt.Println("中间件方法")
  4. }
  5. func ApiRoutersInit(router *gin.Engine) {
  6. apiRouter := router.Group("api")
  7. {
  8. // 写法二
  9. apiRouter.GET("list", MiddlewareFunc,func(context *gin.Context) {
  10. context.String(http.StatusOK, "ok")
  11. })
  12. }
  13. }
ctx.Next()

中间件里面加上 ctx.Next()可以让我们在路由匹配完成后执行一些操作

  1. func MiddlewareFunc(context *gin.Context) {
  2. fmt.Println("请求执行前")
  3. // 调用该请求的剩余处理程序
  4. context.Next()
  5. // 执行后面的func(context *gin.Context)方法
  6. // 每调用一次 context.Next() ,向后执行一个func(context *gin.Context)
  7. // 执行完之后再执行打印
  8. fmt.Println("请求执行完成")
  9. }
ctx.Abort

Abort 是终止的意思, ctx.Abort() 表示终止调用该请求的剩余处理程序

  1. func MiddlewareFunc(context *gin.Context) {
  2. fmt.Println("aaa")
  3. // 终止该请求的剩余处理程序
  4. context.Abort()
  5. fmt.Println("这里继续打印")
  6. }

全局中间件

  1. func main() {
  2. router := gin.Default()
  3. // 在匹配路由之前配置全局中间件
  4. // 使用Use配置全局中间件,参数就是中间件方法,可以传入多个,
  5. router.Use(MiddlewareFunc1,MiddlewareFunc2)
  6. router.GET("/", func(context *gin.Context) {
  7. context.String(http.StatusOK, "ok")
  8. })
  9. // 将默认引擎传给其他文件定义的接收引擎的方法
  10. api.ApiRoutersInit(router)
  11. router.Run()
  12. }

路由分组中间件

方法一
  1. func ApiRoutersInit(router *gin.Engine) {
  2. // 在路由分组的Group后配置中间件
  3. apiRouter := router.Group("api",MiddlewareFunc)
  4. {
  5. apiRouter.GET("list",
  6. // 执行请求
  7. func(context *gin.Context) {
  8. context.String(http.StatusOK, "ok")
  9. })
  10. }
  11. }
方法二
  1. func ApiRoutersInit(router *gin.Engine) {
  2. apiRouter := router.Group("api")
  3. // 调用group对象 配置中间件
  4. apiRouter.Use(MiddlewareFunc)
  5. {
  6. apiRouter.GET("list",
  7. // 执行请求
  8. func(context *gin.Context) {
  9. context.String(http.StatusOK, "ok")
  10. })
  11. }
  12. }

中间件和对应控制器共享数据

  1. // 中间件
  2. func MiddlewareFunc(context *gin.Context) {
  3. // 通过Set设置一个数据 k,v
  4. context.Set("name", "li")
  5. }
  1. // 控制器
  2. func (a ApiController) ApiSetInfo(context *gin.Context) {
  3. // 通过.Get(key) 获取值,获取到的是一个any类型的值和是否异常的bool
  4. username, _ := context.Get("name")
  5. // 通过类型断言获取string类型的name
  6. name, _ := username.(string)
  7. context.String(http.StatusOK, name)
  8. }

中间件注意事项

gin默认中间件

gin.Default()默认使用了 Logger 和 Recovery 中间件,其中:

? Logger 中间件将日志写入 gin.DefaultWriter,即使配置了 GIN_MODE=release。

? Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入 500 响应码。

如果不想使用上面两个默认的中间件,可以使用 gin.New()新建一个没有任何默认中间件的路由

中间件中使用协程

当在中间件或 handler 中启动新的 goroutine 时,不能使用原始的上下文(c *gin.Context),必须使用其只读副本(c.Copy())

  1. func MiddlewareFunc(context *gin.Context) {
  2. c := context.Copy()
  3. go func() {
  4. fmt.Println("url是", c.Request.URL)
  5. }()
  6. go func() {
  7. fmt.Println("body是", c.Request.Body)
  8. }()
  9. }
  10. // 不需要wait等待协程完成,因为主程序main.go会一直执行

model

如果我们的应用非常简单的话,我们可以在 Controller 里面处理常见的业务逻辑。但是如果我们有一个功能想在多个控制器、或者多个模板里面复用的话,那么我们就可以把公共的功能单独抽取出来作为一个模块(Model)。 Model 是逐步抽象的过程,一般我们会在 Model里面封装一些公共的方法让不同 Controller 使用,也可以在 Model 中实现和数据库的交互

自定义一个models包,把通用的一些功能抽离来封装好,供其他地方调用,简单说models的概念就是封装一些公共方法

  1. /*
  2. */
  3. package models
  4. import "time"
  5. // 将时间戳转换为日期
  6. func UnixToTime(timestamp int) string {
  7. t := time.Unix(int64(timestamp), 0)
  8. return t.Format("2006-01-02 15:04:05")
  9. }

原文链接:https://www.cnblogs.com/Mickey-7/p/18036593

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号