IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

gin系列-中间件

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

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

定义中间件

Gin中的中间件必须是一个gin.HandlerFunc类型

入门案例

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    c.JSON(http.StatusOK, gin.H{
        "msg": "indx",
    })
}

//定义一个中间件
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
}

func main() {
    r := gin.Default()
    //GET(relativePath string, handlers ...HandlerFunc) IRoutes
    r.GET("/index",m1,indexHandler)
    //r.GET("/index", func(c *gin.Context) {
    //  c.JSON(http.StatusOK, gin.H{
    //      "msg": "indx",
    //  })
    //})
    r.Run(":9090")
}

[GIN-debug] Listening and serving HTTP on :9090
m1 in ....
index in ...
[GIN] 2020/04/21 - 15:21:31 |?[97;42m 200 ?[0m|       998.3µs |       127.0.0.1 |?[97;44m GET     ?[0m "/index"

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    c.JSON(http.StatusOK, gin.H{
        "msg": "indx",
    })
}

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    //输出
    // m1 in ....
    //index in ...
    //cost:%v
    // 996.8µs
}

func main() {
    r := gin.Default()
    //GET(relativePath string, handlers ...HandlerFunc) IRoutes
    r.GET("/index",m1,indexHandler)  //先执行m1函数再执行indexHandler函数
    //r.GET("/index", func(c *gin.Context) {
    //  c.JSON(http.StatusOK, gin.H{
    //      "msg": "indx",
    //  })
    //})
    r.Run(":9090")
}

注册中间件

在gin框架中,可以为每个路由添加任意数量的中间件。

为全局路由注册

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    c.JSON(http.StatusOK, gin.H{
        "msg": "indx",
    })
}

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
    //输出
    // [GIN-debug] Listening and serving HTTP on :9090
    //m1 in ....
    //m2 in ....
    //index in ...
    //m2 out
    //cost:%v
    // 997.3µs
    //m1 out
}


func m2(c *gin.Context)  {
    fmt.Println("m2 in ....")
    c.Next() //调用后续的处理函数
    fmt.Println("m2 out")
}

func main() {
    r := gin.Default()
    r.Use(m1,m2) //全局注册中间件函数m1,m2    洋葱模型   类似递归调用
    //GET(relativePath string, handlers ...HandlerFunc) IRoutes
    //r.GET("/index",m1,indexHandler)  //先执行m1函数再执行indexHandler函数
    r.GET("/index",indexHandler)
    r.GET("/shop", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    r.GET("/user", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    r.Run(":9090")
}

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    c.JSON(http.StatusOK, gin.H{
        "msg": "indx",
    })
}

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
    //输出
    // [GIN-debug] Listening and serving HTTP on :9090
    //m1 in ....
    //m2 in ....
    //m2 out
    //cost:%v
    // 997.8µs
    //m1 out
}


func m2(c *gin.Context)  {
    fmt.Println("m2 in ....")
    //c.Next() //调用后续的处理函数
    c.Abort() //阻止后续调用
    //return   //return 立即结束m2函数 
    //m1 in ....
    //m2 in ....
    //cost:%v
    // 0s
    //m1 out

    fmt.Println("m2 out")
}

//func authMiddleware(c *gin.Context)  {   //通常写成闭包
//  //是否登陆的判断
//  //if 是登陆用户
//  //c.Next()
//  //else
//  //c.Abort()
//}

func authMiddleware(doCheck bool)gin.HandlerFunc {   //开关注册
    //连接数据库
    //或着其他准备工作
    return func(c *gin.Context) {
        if doCheck {
            //是否登陆的判断
            //if 是登陆用户
            //c.Next()
            //else
            //c.Abort()
        } else {
            c.Next()
        }
    }

}

func main() {
    r := gin.Default()
    r.Use(m1,m2,authMiddleware(true)) //全局注册中间件函数m1,m2    洋葱模型   类似递归调用
    //GET(relativePath string, handlers ...HandlerFunc) IRoutes
    //r.GET("/index",m1,indexHandler)  //先执行m1函数再执行indexHandler函数
    r.GET("/index",indexHandler)
    r.GET("/shop", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    r.GET("/user", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    r.Run(":9090")
}

为某个路由单独注册

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
}

func main() {
    r := gin.Default()
    r.GET("/user", m1, func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    //m1 in ....
    //cost:%v
    // 0s
    //m1 out
    r.Run(":9090")
}

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    c.JSON(http.StatusOK, gin.H{
        "msg": "indx",
    })
}

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
}


func m2(c *gin.Context)  {
    fmt.Println("m2 in ....")
    //c.Next() //调用后续的处理函数
    c.Abort() //阻止后续调用
    //return   //return 立即结束m2函数
    //m1 in ....
    //m2 in ....
    //cost:%v
    // 0s
    //m1 out

    fmt.Println("m2 out")
}

func main() {
    r := gin.Default()
    r.GET("/user", m1,m2, func(c *gin.Context) {  //可以单独多个路由
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    //[GIN-debug] Listening and serving HTTP on :9090
    //m1 in ....
    //m2 in ....
    //m2 out
    //cost:%v
    // 0s
    //m1 out
    r.Run(":9090")
}

为路由组注册中间件

func main() {
    //路由组注册中间件方法1:
    xxGroup := r.Group("/xx", authMiddleware(true))
    {
        xxGroup.GET("/index", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{"msg":"xxGroup"})
        })
    }
    //路由组注册中间件方法2:
    xx2Group := r.Group("/xx")
    xx2Group.Use(authMiddleware(true))
    {
        xxGroup.GET("/index", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{"msg":"xxGroup"})
        })
    }
    r.Run(":9090")
}


跨中间件存取值

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    name, ok := c.Get("name")   //从上下文中取值,跨中间件存取值
    if !ok {
        name = "匿名用户"
    }
    c.JSON(http.StatusOK, gin.H{
        "msg": name,
    })
}

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
}


func m2(c *gin.Context)  {
    fmt.Println("m2 in ....")
    c.Set("name","zisefeizhu")  //在上下文中设置c的值
    fmt.Println("m2 out")
}

func authMiddleware(doCheck bool)gin.HandlerFunc {   //开关注册
    //连接数据库
    //或着其他准备工作
    return func(c *gin.Context) {
        if doCheck {
            //是否登陆的判断
            //if 是登陆用户
            c.Next()
            //else
            //c.Abort()
        } else {
            c.Next()
        }
    }

}

func main() {
    r := gin.Default()
    r.Use(m1,m2,authMiddleware(true)) //全局注册中间件函数m1,m2    洋葱模型   类似递归调用
    //GET(relativePath string, handlers ...HandlerFunc) IRoutes
    //r.GET("/index",m1,indexHandler)  //先执行m1函数再执行indexHandler函数
    r.GET("/index",indexHandler)
    r.Run(":9090")
}

109_1.png

中间件注意事项

gin.Default()

gin.Default()默认使用了Logger和Recovery中间件,其中:Logger中间件将日志写入gin.DefaultWriter,即使配置了GIN_MODE=release。Recovery中间件会recover任何panic。如果有panic的话,会写入500响应码。如果不想使用上面两个默认的中间件,可以使用gin.New()新建一个没有任何默认中间件的路由。

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func indexHandler(c *gin.Context) {
    fmt.Println("index in ...")
    name, ok := c.Get("name")   //从上下文中取值,跨中间件存取值
    if !ok {
        name = "匿名用户"
    }
    c.JSON(http.StatusOK, gin.H{
        "msg": name,
    })
}

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
}


func m2(c *gin.Context)  {
    fmt.Println("m2 in ....")
    c.Set("name","zisefeizhu")  //在上下文中设置c的值
    fmt.Println("m2 out")
}

func authMiddleware(doCheck bool)gin.HandlerFunc {   //开关注册
    //连接数据库
    //或着其他准备工作
    return func(c *gin.Context) {
        if doCheck {
            //是否登陆的判断
            //if 是登陆用户
            c.Next()
            //else
            //c.Abort()
        } else {
            c.Next()
        }
    }

}

func main() {
    //r := gin.Default()  //默认使用Logger()和Recovery()中间件
    r := gin.New()
    r.Use(m1,m2,authMiddleware(true)) //全局注册中间件函数m1,m2    洋葱模型   类似递归调用
    r.GET("/index",indexHandler)
    r.GET("/shop", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    r.GET("/user", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "index",
        })
    })
    r.Run(":9090")
}

[GIN-debug] Listening and serving HTTP on :9090
m1 in ....
m2 in ....
m2 out
index in ...
cost:%v
 1.0137ms
m1 out

109_2.png

gin中间件中使用goroutine

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

//定义一个中间件:统计耗时
func m1(c *gin.Context)  {
    fmt.Println("m1 in ....")
    //计时
    start := time.Now()
    go funcXX(c.Copy()) //在funcXX中只能使用c的拷贝
    c.Next() //调用后续的处理函数 执行indexHandler函数
    //c.Abort() //阻止调用后续的处理函数
    cost := time.Since(start)
    fmt.Println("cost:%v\n", cost)
    fmt.Println("m1 out")
}

文章永久链接:https://tech.souyunku.com/?p=38576


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(69) 打赏



未经允许不得转载:搜云库技术团队 » gin系列-中间件

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367