首页 > 其他分享 >Gin中间件

Gin中间件

时间:2024-01-17 11:14:25浏览次数:23  
标签:GET fmt 中间件 api apiRouters gin Gin

Gin中间件

1 中间件简介

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

*/

在gin中的Default的方法中已经有两个中间件了:

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
    debugPrintWARNINGDefault()
    engine := New()
    engine.Use(Logger(), Recovery())// 日志和异常恢复中间件
    return engine
}

如果我们想创建一个没有任何中件的router可以通过New方法:

router := gin.New()

然后可以在这个router中使用中间件:

func main() {
    // 创建一个不包含中间件的路由器
    r := gin.New()

    // 全局中间件
    // 使用 Logger 中间件
    r.Use(gin.Logger())

    // 使用 Recovery 中间件
    r.Use(gin.Recovery())

    // 路由添加中间件,可以添加任意多个
    r.GET("/benchmark", MyBenchLogger(), benchEndpoint)

    // 路由组中添加中间件
    // authorized := r.Group("/", AuthRequired())
    // exactly the same as:
    authorized := r.Group("/")
    // per group middleware! in this case we use the custom created
    // AuthRequired() middleware just in the "authorized" group.
    authorized.Use(AuthRequired())
    {
        authorized.POST("/login", loginEndpoint)
        authorized.POST("/submit", submitEndpoint)
        authorized.POST("/read", readEndpoint)

        // nested group
        testing := authorized.Group("testing")
        testing.GET("/analytics", analyticsEndpoint)
    }

    // Listen and serve on 0.0.0.0:8080
    r.Run(":8080")
}

2 路由添加中间件

package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
)

func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	{
		apiRouters.GET("/", func(context *gin.Context) {
			fmt.Println("欢迎来到api")
		}, api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}
/*
	这时候当我们访问 127.0.0.1:8000/api 时 就会先触发
 	func(context *gin.Context) {
			fmt.Println("欢迎来到api")
	}
	然后才是我们的业务逻辑代码,在业务逻辑代码之前我们可以加无数个中间件
*/

// 也可以这么写
package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
)

func InitMiddleware(c *gin.Context) {
	fmt.Println("欢迎来到api")
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	{
		apiRouters.GET("/", InitMiddleware, api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}

/* 
	需要注意的是 业务逻辑必须放在最后才行
*/

3 如果想在业务逻辑处理完后再执行一些操作怎么办 ------- c.Next()

package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
)

func InitMiddleware(c *gin.Context) {
	fmt.Println("欢迎来到api")
	c.Next()
	fmt.Println("请求结束")
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	{
		apiRouters.GET("/", InitMiddleware, api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}
当我们的中间件加入了c.Next()后
当我们访问  127.0.0.1:8000/api 时
整个运行流程就变为
先执行 fmt.Println("欢迎来到api")

然后是 api.ApiController{}.Api 执行我们的业务逻辑

最后是执行c.Next()后面的代码  fmt.Println("请求结束")

3.1 统计请求处理时间

package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

func InitMiddleware(c *gin.Context) {
	start := time.Now().UnixNano()
	c.Next()
	end := time.Now().UnixNano()
	fmt.Printf("使用了 %vms", end-start)
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	{
		apiRouters.GET("/", InitMiddleware, api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}

4 c.Abort()

package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

func InitMiddleware(c *gin.Context) {
	start := time.Now().UnixNano()
	//c.Next()
	c.Abort()
	end := time.Now().UnixNano()
	fmt.Printf("使用了 %vms", end-start)
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	{
		apiRouters.GET("/", InitMiddleware, api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}
整体运行流程
当我们的中间件加入了c.Abort()后
当我们访问  127.0.0.1:8000/api 时
整个运行流程就变为
先执行 start := time.Now().UnixNano()

然后是 
end := time.Now().UnixNano()
fmt.Printf("使用了 %vms", end-start)

并不会去执行我们的业务逻辑代码

5 多个中间件的执行

package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
)

func InitMiddlewareOne(c *gin.Context) {
	fmt.Println("第一个中间件")
	c.Next()
	fmt.Println("第一个中间件结束")
}

func InitMiddlewareTwo(c *gin.Context) {
	fmt.Println("第二个中间件")
	c.Next()
	fmt.Println("第二个中间件结束")
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	{
		apiRouters.GET("/", InitMiddlewareOne, InitMiddlewareTwo, api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}

pFFBhYq.png

6 全局中间件

全局中间件需要在main.go中配置

package main

import (
	"awesomeProject/gin/routers"
	"encoding/xml"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)


func InitMiddlewareOne(c *gin.Context) {
	fmt.Println("第一个中间件")
	c.Next()
	fmt.Println("第一个中间件结束")
}

func InitMiddlewareTwo(c *gin.Context) {
	fmt.Println("第二个中间件")
	c.Next()
	fmt.Println("第二个中间件结束")
}
func main() {
	r := gin.Default()
	r.Use(InitMiddlewareOne)   // 添加中间件 单个中间件
    r.Use(InitMiddlewareOne, InitMiddlewareTwo) // 多个中间件 多个中间件的运行流程与上面的一样
	routers.AdminRoutersInit(r)
	routers.ApiRoutersInit(r)
	routers.DefaultRoutersInit(r)
	r.Run(":8000") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

7 路由分组中配置中间件

第一种方法

package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
)

func InitMiddlewareOne(c *gin.Context) {
	fmt.Println("第一个中间件")
	c.Next()
	fmt.Println("第一个中间件结束")
}

func InitMiddlewareTwo(c *gin.Context) {
	fmt.Println("第二个中间件")
	c.Next()
	fmt.Println("第二个中间件结束")
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api")
	apiRouters.Use(InitMiddlewareOne) // 直接使用Use,配置中间件
	{
		apiRouters.GET("/",api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}
package routers

import (
	"awesomeProject/gin/controllers/api"
	"fmt"
	"github.com/gin-gonic/gin"
)

func InitMiddlewareOne(c *gin.Context) {
	fmt.Println("第一个中间件")
	c.Next()
	fmt.Println("第一个中间件结束")
}

func InitMiddlewareTwo(c *gin.Context) {
	fmt.Println("第二个中间件")
	c.Next()
	fmt.Println("第二个中间件结束")
}
func ApiRoutersInit(r *gin.Engine) {
	apiRouters := r.Group("/api",InitMiddlewareOne // 直接在后面加中间件
	{
		apiRouters.GET("/", api.ApiController{}.Api)
		apiRouters.GET("/userlist", api.ApiController{}.ApiUserList)
		apiRouters.GET("/plist", api.ApiController{}.ApiPlist)
		apiRouters.GET("/cart", api.ApiController{}.ApiCart)
	}
}

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

使用 c.Set() 设置数据

获取数据 c.Get() 

标签:GET,fmt,中间件,api,apiRouters,gin,Gin
From: https://www.cnblogs.com/chunyouqudongwuyuan/p/17969502

相关文章

  • Gin 文件上传 按照日期存储
    Gin文件上传按照日期存储1实现步骤/* 1.获取上传的文件 2.获取后缀名判断类型是否正确.jpg.png.gif.jpeg 3.创建图片保存目录static/upload/20240101 4.生成文件名称和文件保存的目录 5.保存*/2代码//获取当前的日期funcGetDay()string{ template:="......
  • Gin中的Session
    Gin中的Session1Session简单介绍session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存在服务器上。2Session的工作流程当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个session对象,生成一个类似于key,value的键值对,然后将va......
  • Gin中的Cookie
    Gin中的Cookie1Cookie简介/* ●HTTP是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页面,服务器无法认识到这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何关系的。如果我们要实现多个页面之间共享数据的话我们就可以使用Cookie或者Sessio......
  • GIn入门
    Gin入门1.Gin安装goget-ugithub.com/gin-gonic/gin2.将gin引入到代码中:import"github.com/gin-gonic/gin"2.1(可选)如果使用诸如http.StatusOK之类的常量,则需要引入net/http包:import"net/http"2.2初始化gomodgomodinit/*生成go.mod文件,此命令会在当......
  • 出现了HTTPSConnectionPool(host=‘huggingface.co‘, port=443)错误的解决方法
    在下载huggingface模型的时候,经常会出现这个错误,HTTPSConnectionPool(host=‘huggingface.co’,port=443)。如在下载Tokenizer的时候,tokenizer=AutoTokenizer.from_pretrained("csebuetnlp/mT5_multilingual_XLSum")就会出现以上的错误HTTPSConnectionPool(host=‘hug......
  • Inserting a node at beginning,全局变量头指针【1月16日学习笔记】
    点击查看代码//insertinganodeatbeginning,全局变量头指针#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};node*A;voidinsert(intx){ node*temp=newnode;//创建新节点 temp->data=x; temp->next=A;//新节点尾巴指......
  • Inserting a node at beginning,局部变量头指针版本1【1月16日学习笔记】
    点击查看代码//insertinganodeatbeginning,局部变量头指针版本1#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};node*insert(intx,node*A){ node*temp=newnode;//创建新节点 temp->data=x; temp->next=A;//新节......
  • Inserting a node at beginning,局部变量头指针版本2【1月16日学习笔记】
    点击查看代码//insertinganodeatbeginning,局部变量头指针版本2#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};voidinsert(intx,node**A){ node*temp=newnode;//创建新节点 temp->data=x; temp->next=*A;//新......
  • FlaskSQLAlchemy中的Pagination类型对象
    FlaskSQLAlchemy中的Pagination类型对象。一个Query对象调用paginate方法就获得了Pagination对象。paginate方法传入了两个参数,一个是当前页,另一个是每一页最多显示多少博客。paginate的返回值为代表当前页的Pagination对象。一个Paginationi对象的常用属性有:items当前页面中的......
  • 15、nginx的rewrite机制
    1.概述Rewrite主要的功能就是实现URL的重写。Nginx的Rewrite规则采用PCRE(PerlCompatibleRegularExpressions)Perl兼容正则表达式的语法进行规则匹配。通过Rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。例如,一些使用MVC框架的程序只有一个入口,可以通过......