gin框架中中间件的编写与使用

概念

  1. 一个完整的系统可能包括鉴权认证、权限管理、安全检查、日志记录等多维度的系统支持。
  2. 中间件位与服务器和实际业务处理程序之间,其含义就相当于在请求和具体的业务处理逻辑之间增加某些操作,这种以额外增加的方式不会影响编码的效率,也不会侵入到框架中。

中间件的位置和角色示意图

  • gin框架中中间件的编写与使用

自定义一个中间件

  • gin中间件的类型是函数,有两条标准
  1. func函数
  2. 返回值是HandlerFunc类型
  • 案例:定义一个log日志的中间件,打印path和Method
package main

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

func main() {
	router := gin.New()

	// 全局使用自定义的中间件
	router.Use(Logger())

	router.GET("/hello", HelloHandle)
	// 单个接口使用自定义的中间件
	router.GET("/index", RemoteAddr(), IndexHandle)

	router.Run(":8000")
}
func Logger() gin.HandlerFunc {
	// 打印请求路径和方法的中间件
	return func(ctx *gin.Context) {
		fmt.Println(ctx.FullPath(), ctx.Request.Method)
	}
}
func RemoteAddr() gin.HandlerFunc {
	// 打印远程地址的中间件
	return func(context *gin.Context) {
		fmt.Println(context.Request.RemoteAddr)
	}
}
func HelloHandle(ctx *gin.Context) {
	ctx.Writer.Write([]byte("hello world!"))
}
func IndexHandle(ctx *gin.Context) {
	ctx.Writer.Write([]byte("hello index!"))
}

context.Next函数

  • contentx.Next函数可以将中间件代码的执行顺序一分为二,Next函数之前的代码在请求处理之前执行,当执行到Next函数时会中断向下执行,去执行具体的业务逻辑代码,当业务逻辑代码执行完成后,在继续执行Next函数后面的代码。
  • 案例
package main

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

func main() {
	router := gin.Default()

	// 全局使用自定义的中间件
	router.Use(Logger())

	router.GET("/hello", HelloHandle)
	// 单个接口使用自定义的中间件
	router.GET("/index", RemoteAddr(), IndexHandle)

	router.Run(":8000")
}
func Logger() gin.HandlerFunc {
	// 打印请求路径和方法的中间件
	return func(ctx *gin.Context) {
		fmt.Println(ctx.FullPath(), ctx.Request.Method)
		fmt.Println("状态码", ctx.Writer.Status())
		ctx.Next()
		fmt.Println("状态码", ctx.Writer.Status())
	}
}
func RemoteAddr() gin.HandlerFunc {
	// 打印远程地址的中间件
	return func(context *gin.Context) {
		fmt.Println(context.Request.RemoteAddr)

		// 中断执行,去执行接口业务代码,接口业务执行完毕后在回来执行context.Next()后面的代码
		context.Next()

		status := context.Writer.Status()
		fmt.Println("状态码:", status)
	}
}
func HelloHandle(ctx *gin.Context) {
	ctx.String(http.StatusNotFound, "404 not found")
	fmt.Println("hello接口执行完了")
}
func IndexHandle(ctx *gin.Context) {
	fmt.Println("index函数执行了")
	ctx.Writer.Write([]byte("hello index!"))
}
上一篇:go gin框架:通过gin的StaticFile来加载html网页


下一篇:Go项目实现优雅关机与平滑重启