当前位置: 首页 > news >正文

汽车销售管理系统重庆seo网络优化师

汽车销售管理系统,重庆seo网络优化师,吉林文明网设计专门页面,做h5页面的网站哪个好Go web框架——Gin中间件与路由 1 单独注册中间件1.1 入门案例1.2 多个中间件1.3 中间件拦截响应1.4 中间件放行 2 全局注册中间件3 自定义参数传递4 路由分组4.1 入门案例4.2 路由分组注册中间件4.3 综合使用 5 使用内置的中间件6 中间件案例权限验证耗时统计 1 单独注册中间件…

Go web框架——Gin中间件与路由

    • 1 单独注册中间件
      • 1.1 入门案例
      • 1.2 多个中间件
      • 1.3 中间件拦截响应
      • 1.4 中间件放行
    • 2 全局注册中间件
    • 3 自定义参数传递
    • 4 路由分组
      • 4.1 入门案例
      • 4.2 路由分组注册中间件
      • 4.3 综合使用
    • 5 使用内置的中间件
    • 6 中间件案例
      • 权限验证
      • 耗时统计

1 单独注册中间件

Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等
即比如,如果访问一个网页的话,不管访问什么路径都需要进行登录,此时就需要为所有路径的处理函数进行统一一个中间件

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

1.1 入门案例

我们先看一下Get函数能够接收的参数:

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {return group.handle(http.MethodGet, relativePath, handlers)
}type HandlerFunc func(*Context)

从这个函数里,我们能看到它可以,它可以接收很多的HandlerFunc类型的数据,并且发现是func(*Context)数据类型都可以,所以,我们可以定义很多个中间件,它必须是*gin.Context类型

  1. 定义一个中间件
func m1(c *gin.Context) {fmt.Println("m1 in.........")
}
  1. 写一个函数,在前端响应的数据,作为参考
func indexHandler(c *gin.Context) {fmt.Println("index.....")c.JSON(http.StatusOK, gin.H{"msg": "index",})
}
  1. 完整代码
func indexHandler(c *gin.Context) {fmt.Println("index.....")c.JSON(http.StatusOK, gin.H{"msg": "index",})
}// 定义一个中间件
func m1(c *gin.Context) {fmt.Println("m1 in.........")
}func main() {r := gin.Default()//m1处于indexHandler函数的前面,请求来之后,先走m1,再走indexr.GET("/index", m1, indexHandler)r.Run(":8000")
}

注意:m1处于indexHandler函数的前面,请求来之后,先走m1,再走index

然后,使用游览器访问对应的请求,看一下输出:

image-20231028220548688

验证完毕!!~

1.2 多个中间件

router.GET,后面可以跟很多HandlerFunc方法,这些方法其实都可以叫中间件

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m1(c *gin.Context) {fmt.Println("m1 ...in")
}
func m2(c *gin.Context) {fmt.Println("m2 ...in")
}func main() {router := gin.Default()router.GET("/", m1, func(c *gin.Context) {fmt.Println("index ...")c.JSON(200, gin.H{"msg": "响应数据"})}, m2)router.Run(":8080")
}

这里就不演示了~~

1.3 中间件拦截响应

c.Abort()函数,作用:拦截,后续的HandlerFunc就不会执行了

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m1(c *gin.Context) {fmt.Println("m1 ...in")c.JSON(200, gin.H{"msg": "第一个中间件拦截了"})c.Abort()
}
func m2(c *gin.Context) {fmt.Println("m2 ...in")
}func main() {router := gin.Default()router.GET("/", m1, func(c *gin.Context) {fmt.Println("index ...")c.JSON(200, gin.H{"msg": "响应数据"})}, m2)router.Run(":8080")
}

运行后,去游览器试一下,会发现只输出:m1 …in,也就是被第一个拦截器拦截了~

1.4 中间件放行

c.Next()函数,作用:Next前后形成了其他语言中的请求中间件和响应中间件

package mainimport ("fmt""github.com/gin-gonic/gin"
)func m1(c *gin.Context) {fmt.Println("m1 ...in")c.Next()fmt.Println("m1 ...out")
}
func m2(c *gin.Context) {fmt.Println("m2 ...in")c.Next()fmt.Println("m2 ...out")
}func main() {router := gin.Default()router.GET("/", m1, func(c *gin.Context) {fmt.Println("index ...in")c.JSON(200, gin.H{"msg": "响应数据"})c.Next()fmt.Println("index ...out")}, m2)router.Run(":8080")
}

输出结果:

m1 ...in
index ...in 
m2 ...in    
m2 ...out   
index ...out
m1 ...out   

输出的方式,有点像栈,先进去的m1...out最后再输出~

2 全局注册中间件

在Gin框架中,可以使用Use方法注册全局中间件。全局中间件会对所有的请求都生效。

func main() {r := gin.Default()r.Use(Logger()) // 注册全局中间件r.GET("/hello", HelloHandler)r.Run(":8080")
}// Logger 是一个全局中间件
func Logger() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()c.Next()end := time.Now()latency := end.Sub(start)log.Printf("[%s] %s %s %v", c.Request.Method, c.Request.URL.Path, c.Request.RemoteAddr, latency)}
}func HelloHandler(c *gin.Context) {c.String(http.StatusOK, "Hello, Gin!")
}

在上面的示例中,Logger函数是一个全局中间件。它在处理请求之前记录了请求的相关信息,并在请求处理完成后打印了请求的耗时。

3 自定义参数传递

在中间件之间传递自定义参数是一种常见的需求。在Gin框架中,可以使用Context.SetContext.Get方法来传递自定义参数,并且传递的数据是一个key-value

func main() {r := gin.Default()r.Use(AddCustomData("custom data"))r.GET("/hello", HelloHandler)r.Run(":8080")
}func AddCustomData(data string) gin.HandlerFunc {return func(c *gin.Context) {c.Set("customData", data) // 设置自定义参数c.Next()}
}func HelloHandler(c *gin.Context) {customData, exists := c.Get("customData") // 获取自定义参数if exists {c.String(http.StatusOK, "Hello, Gin! Custom data: %s", customData)} else {c.String(http.StatusOK, "Hello, Gin!")}
}

在上面的示例中,AddCustomData函数返回了一个中间件函数,用于在Context中设置自定义参数。在HelloHandler处理函数中,通过Context.Get方法获取自定义参数并使用。

4 路由分组

4.1 入门案例

将一系列的路由放到一个组下,统一管理。例如,以下的路由前面统一加上api的前缀

package mainimport "github.com/gin-gonic/gin"func main() {router := gin.Default()r := router.Group("/api")r.GET("/index", func(c *gin.Context) {c.String(200, "index")})r.GET("/home", func(c *gin.Context) {c.String(200, "home")})router.Run(":8080")
}

4.2 路由分组注册中间件

package mainimport ("fmt""github.com/gin-gonic/gin"
)func middle(c *gin.Context) {fmt.Println("middle ...in")
}func main() {router := gin.Default()r := router.Group("/api").Use(middle)  // 可以链式,也可以直接r.Use(middle)r.GET("/index", func(c *gin.Context) {c.String(200, "index")})r.GET("/home", func(c *gin.Context) {c.String(200, "home")})router.Run(":8080")
}

这样写我们就可以指定哪一些分组下可以使用中间件了

当然,中间件还有一种写法,就是使用函数加括号的形式

package mainimport ("fmt""github.com/gin-gonic/gin"
)func middle(c *gin.Context) {fmt.Println("middle ...in")
}
func middle1() gin.HandlerFunc {// 这里的代码是程序一开始就会执行return func(c *gin.Context) {// 这里是请求来了才会执行fmt.Println("middle1 ...inin")}
}func main() {router := gin.Default()r := router.Group("/api").Use(middle, middle1())r.GET("/index", func(c *gin.Context) {c.String(200, "index")})r.GET("/home", func(c *gin.Context) {c.String(200, "home")})router.Run(":8080")
}

4.3 综合使用

设置了一个中间件进行身份验证,并且还对路由进行分组,分为两组来使用

func main() {r := gin.Default()r.Use(Logger()) // 注册全局中间件v1 := r.Group("/v1")v1.Use(Auth()) // 注册 v1 路由组的局部中间件{v1.GET("/hello", HelloHandler)v1.GET("/user", UserHandler)}r.GET("/hello", HelloHandler) // 其他路由不使用 Auth 中间件r.Run(":8080")
}func Auth() gin.HandlerFunc {return func(c *gin.Context) {// 进行身份验证的逻辑if IsAuthenticated {c.Next()} else {c.AbortWithStatus(http.StatusUnauthorized)}}
}func HelloHandler(c *gin.Context) {c.String(http.StatusOK, "Hello, Gin!")
}func UserHandler(c *gin.Context) {c.String(http.StatusOK, "User Info")
}// Logger 是一个全局中间件
func Logger() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()c.Next()end := time.Now()latency := end.Sub(start)log.Printf("[%s] %s %s %v", c.Request.Method, c.Request.URL.Path, c.Request.RemoteAddr, latency)}
}

5 使用内置的中间件

Gin框架内置了一些常用的中间件,可以直接使用。以下是一些常用的内置中间件和示例:

  • gin.Logger():记录请求日志
  • gin.Recovery():处理请求时的恢复机制
func main() {r := gin.Default()r.Use(gin.Logger()) // 使用 gin.Logger() 中间件r.Use(gin.Recovery()) // 使用 gin.Recovery() 中间件r.GET("/hello", HelloHandler)r.Run(":8000")
}func HelloHandler(c *gin.Context) {c.String(http.StatusOK, "Hello, Gin!")
}

不过,平常我们不使用这两个中间件的时候,一样会有记录,所以我们看一下gin.Default函数

func Default() *Engine {debugPrintWARNINGDefault()engine := New()engine.Use(Logger(), Recovery())return engine
}

从这段代码就可以看出,是默认使用了这两个函数,一般自动调用了~~~

6 中间件案例

权限验证

以前后端最流行的jwt为例,如果用户登录了,前端发来的每一次请求都会在请求头上携带上token

后台拿到这个token进行校验,验证是否过期,是否非法

如果通过就说明这个用户是登录过的

不通过就说明用户没有登录

package mainimport ("github.com/gin-gonic/gin"
)func JwtTokenMiddleware(c *gin.Context) {// 获取请求头的tokentoken := c.GetHeader("token")// 调用jwt的验证函数if token == "1234" {// 验证通过c.Next()return}// 验证不通过c.JSON(200, gin.H{"msg": "权限验证失败"})c.Abort()
}func main() {router := gin.Default()api := router.Group("/api")apiUser := api.Group(""){apiUser.POST("login", func(c *gin.Context) {c.JSON(200, gin.H{"msg": "登录成功"})})}apiHome := api.Group("system").Use(JwtTokenMiddleware){apiHome.GET("/index", func(c *gin.Context) {c.String(200, "index")})apiHome.GET("/home", func(c *gin.Context) {c.String(200, "home")})}router.Run(":8080")
}

耗时统计

统计每一个视图函数的执行时间

func TimeMiddleware(c *gin.Context) {startTime := time.Now()c.Next()since := time.Since(startTime)// 获取当前请求所对应的函数f := c.HandlerName()fmt.Printf("函数 %s 耗时 %d\n", f, since)
}

文章转载自:
http://nonflammable.rywn.cn
http://sandcastle.rywn.cn
http://gorgeous.rywn.cn
http://galavant.rywn.cn
http://seizor.rywn.cn
http://arguably.rywn.cn
http://enthrallment.rywn.cn
http://phoronid.rywn.cn
http://diphosphoglycerate.rywn.cn
http://featheredged.rywn.cn
http://pascual.rywn.cn
http://portia.rywn.cn
http://bushmanoid.rywn.cn
http://haggis.rywn.cn
http://muddy.rywn.cn
http://diva.rywn.cn
http://modularization.rywn.cn
http://louvred.rywn.cn
http://sinaean.rywn.cn
http://knobstick.rywn.cn
http://klamath.rywn.cn
http://sepiolite.rywn.cn
http://helicon.rywn.cn
http://overextend.rywn.cn
http://sobriquet.rywn.cn
http://cryocable.rywn.cn
http://guiltiness.rywn.cn
http://bizerte.rywn.cn
http://coeditor.rywn.cn
http://episcopize.rywn.cn
http://shellwork.rywn.cn
http://carrycot.rywn.cn
http://frobnitz.rywn.cn
http://federatively.rywn.cn
http://weakliness.rywn.cn
http://laxness.rywn.cn
http://alleged.rywn.cn
http://bahuvrihi.rywn.cn
http://allodiality.rywn.cn
http://plentitude.rywn.cn
http://sayest.rywn.cn
http://huxley.rywn.cn
http://deepfelt.rywn.cn
http://unscented.rywn.cn
http://unrivaled.rywn.cn
http://eradication.rywn.cn
http://collocation.rywn.cn
http://nostalgist.rywn.cn
http://lobby.rywn.cn
http://futurity.rywn.cn
http://endermic.rywn.cn
http://subsidise.rywn.cn
http://signee.rywn.cn
http://mcat.rywn.cn
http://emanative.rywn.cn
http://rhyparography.rywn.cn
http://alberich.rywn.cn
http://contranatural.rywn.cn
http://prealtar.rywn.cn
http://carabin.rywn.cn
http://sclerotized.rywn.cn
http://everlasting.rywn.cn
http://tonalist.rywn.cn
http://norethynodrel.rywn.cn
http://exornation.rywn.cn
http://jazzman.rywn.cn
http://oyes.rywn.cn
http://dejectile.rywn.cn
http://prussianize.rywn.cn
http://interphone.rywn.cn
http://centaurus.rywn.cn
http://unconceivable.rywn.cn
http://wsj.rywn.cn
http://belted.rywn.cn
http://flippantly.rywn.cn
http://positron.rywn.cn
http://examinee.rywn.cn
http://thermoform.rywn.cn
http://bandleader.rywn.cn
http://rattailed.rywn.cn
http://sonochemical.rywn.cn
http://ciliation.rywn.cn
http://palette.rywn.cn
http://metalogue.rywn.cn
http://methyltransferase.rywn.cn
http://manxwoman.rywn.cn
http://holistic.rywn.cn
http://lobation.rywn.cn
http://condensable.rywn.cn
http://dilation.rywn.cn
http://evaporograph.rywn.cn
http://coalfish.rywn.cn
http://adit.rywn.cn
http://employer.rywn.cn
http://bronchiole.rywn.cn
http://faucal.rywn.cn
http://autogenic.rywn.cn
http://vxd.rywn.cn
http://failingly.rywn.cn
http://coupon.rywn.cn
http://www.15wanjia.com/news/95640.html

相关文章:

  • 网站制作软件名字线做手机网站百度关键词排名
  • js实现网站滚屏效果百度电脑版官网
  • 东莞网络app关键词排名优化
  • 自动化培训网站建设百度推广外推联系方式
  • 24小时学会网站建设 pdf下载百度seo关键词
  • 湘潭做网站广告的公司seo公司是做什么的
  • wordpress video html5上海百度seo点击软件
  • 如何网站建设注册域名后如何建立网站
  • 云南做网站哪家便宜搜索引擎优化的流程是什么
  • 安全联盟这种网站建设百度一下 你知道首页
  • 网站建设前景怎么样网站营销网站营销推广
  • 微信制作网站开发今日新闻摘抄
  • WordPress海报封面主题上海专业seo服务公司
  • 招聘网页制作人员seo营销怎么做
  • 专业团队电影手机360优化大师官网
  • 网站二级域名武汉网站seo推广公司
  • 深圳品牌网站建设百度如何添加店铺位置信息
  • 智能化建设网站东莞seo
  • 提高网站权重百度权重10的网站
  • 网站域名怎么进行实名认证百度关键词价格查询
  • 网站页面设计报价bt搜索引擎最好用的
  • php可以做移动端网站拼多多关键词优化步骤
  • 武汉网站建设哪家强东莞市网络营销公司
  • 政府通用网站html模板下载引擎网站
  • 小型网站建设源码重庆专业seo
  • 江津区住房和城乡建设委员会网站南宁百度seo软件
  • 山东网站建设公司网站seo批量查询工具
  • 遵义市人民政府门户网站百度广告代理公司
  • wordpress wp query肇庆百度快照优化
  • 番禺品牌型网站企业产品推广运营公司