forked from go/golangs_learn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.5 KiB
110 lines
3.5 KiB
4 years ago
|
# Gin(七):中间件的使用和定义
|
||
|
|
||
|
中间件 `middleware` 在 `golang` 中是一个很重要的概念,与 `java` 中拦截器很相似。通过 gin 源代码来看看中间件代码使用。
|
||
|
|
||
|
# 中间件使用
|
||
|
|
||
|
我们还是回到了 `initRouter` 中 `SetupRouter` 这个方法。
|
||
|
|
||
|
```go
|
||
|
router := gin.Default()
|
||
|
```
|
||
|
|
||
|
我们的项目是从这一行代码开始的,所以我们看看这一行代码做了些什么。打开 `Default` 源码,
|
||
|
|
||
|
```go
|
||
|
func Default() *Engine {
|
||
|
debugPrintWARNINGDefault()
|
||
|
engine := New()
|
||
|
engine.Use(Logger(), Recovery())
|
||
|
return engine
|
||
|
}
|
||
|
```
|
||
|
|
||
|
源码中,首先是 `New` 了一个 `engine` ,紧接着通过 `Use` 方法,传入了 `Logger()` 和 `Recovery()` ,而 `Logger`和 `Recovery` 就是两个中间件。
|
||
|
|
||
|
其中 `Logger` 是对日志进行记录,而 `Recovery` 是对有 `painc`时, 进行 500 的错误处理
|
||
|
|
||
|
查看了源码之后,那么我们也就知道如何使用中间件了。
|
||
|
|
||
|
# 自定义一个中间件
|
||
|
|
||
|
中间件【称为middleware】需要返回 `gin.HandlerFunc` 函数,所以定义返回函数。
|
||
|
|
||
|
```go
|
||
|
// HandleFunc defines the handler used by gin middleware as return value.
|
||
|
type HandleFunc func(*Context)
|
||
|
```
|
||
|
|
||
|
而且 中间件有个 `Next` 函数,在我们定义的众多中间件,会形成一条中间件链,而通过 `Next` 函数来对后面的中间件进行执行。`Next` 函数是在请求前执行,而 `Next` 函数后是在请求后执行。
|
||
|
|
||
|
我们来自己定义一个 `Logger` 日志,新建一个 `middleware` 文件夹,里面新建 `Logger.go`,进行我们自定义的日志展示。
|
||
|
|
||
|
```go
|
||
|
package middleware
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/gin-gonic/gin"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func Logger() gin.HandlerFunc {
|
||
|
return func(context *gin.Context) {
|
||
|
host := context.Request.Host
|
||
|
url := context.Request.URL
|
||
|
method := context.Request.Method
|
||
|
fmt.Printf("%s::%s \t %s \t %s ", time.Now().Format("2006-01-02 15:04:05"), host, url, method)
|
||
|
context.Next()
|
||
|
fmt.Println(context.Writer.Status())
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## 全局中间件
|
||
|
|
||
|
修改 `initRouter` 中的 `SetupRouter` 方法,将我们自定义的中间件进行添加。
|
||
|
|
||
|
```go
|
||
|
router := gin.New()
|
||
|
// 添加自定义的 logger 中间件
|
||
|
router.Use(middleware.Logger(), gin.Recovery())
|
||
|
```
|
||
|
|
||
|
此时重新启动我们的项目,访问`localhost:8080`端口,控制台上就会打印出我们新的格式日志。
|
||
|
|
||
|
> 2019-07-23 18:17:58::localhost:8080 / GET 200
|
||
|
|
||
|
当然,此时此刻的 `Logger` 中间件是全局使用,我们也可以给特定的路由进行使用。
|
||
|
|
||
|
## 局部中间件
|
||
|
|
||
|
比如我们规定某些路由需要登录后才能访问,那么我们可以给这些路由进行授权管理。
|
||
|
|
||
|
我们重新写一个 `Auth` 中间件来进行管理,这里不具体实现该中间件,后期会实现,这里只进行展示。
|
||
|
|
||
|
```go
|
||
|
package middleware
|
||
|
|
||
|
import "github.com/gin-gonic/gin"
|
||
|
|
||
|
func Auth() gin.HandlerFunc {
|
||
|
return func(context *gin.Context) {
|
||
|
println("已经授权")
|
||
|
context.Next()
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
我们在 用户信息修改和用户信息展示的路由上进行该中间件的添加。
|
||
|
|
||
|
```go
|
||
|
userRouter.GET("/profile/", middleware.Auth(), handler.UserProfile)
|
||
|
userRouter.POST("/update", middleware.Auth(), handler.UpdateUserProfile)
|
||
|
```
|
||
|
|
||
|
再次运行项目,当我们对用户详情页进行访问的时候,控制台上会打印出 已经授权 的日志,而访问其他页面则不会出现,说明我们的中间件使用成功。
|
||
|
|
||
|
# 总结
|
||
|
|
||
|
通过本次的中间件了解,基本掌握了中间件如何编写和使用,对于全局和局部的两种中间件也有着不同的使用方法和使用范围。
|