一. Controller
用不同的Controller
可以实现业务的分类,不同类型的请求可以共用同一套中间件
1.1 单文件Controller
几乎等同于函数封装,直接将ctrl
的代码写入到一个文件里然后调用:
package admin
import (
"net/http"
"github.com/gin-gonic/gin"
)
func Index(ctx *gin.Context) {
ctx.String(http.StatusOK, "首页")
}
调用:
package main
import (
"kanna-web/controller/admin"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", admin.Index)
r.Run(":80")
}
1.2 Controller类与继承
这个和类的写法也是一样的:
package admin
import (
"net/http"
"github.com/gin-gonic/gin"
)
type UserController struct {
}
type AdminController struct {
UserController
}
func (c AdminController) Index(ctx *gin.Context) {
ctx.String(http.StatusOK, "首页")
}
func (c AdminController) Page(ctx *gin.Context) {
ctx.String(http.StatusOK, "Page")
}
调用:
package main
import (
"kanna-web/controller/admin"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", admin.AdminController{}.Index)
r.GET("/page/", admin.AdminController{}.Page)
r.Run(":80")
}
二. 中间件
中间件就是在Router
到Controller
之间可以执行的代码,可以给单个路由添加,也可以路由组添加,也可以全局添加。
2.1 Default or New
在我们创建路由的时候,是gin.Default()
,即包含了:Logger
和Recover
这两个中间件。
如果不需要使用者两个中间件可以gin.New()
。
中间件可以拿来鉴权等各种功能。
2.2 中间件的使用
最基本的形式:
func baseMid(ctx *gin.Context) {
fmt.Println("我进入了中间件")
}
func main() {
r := gin.Default()
r.GET("/", baseMid, admin.AdminController{}.Index)
r.Run(":80")
}
路由组:
func main() {
r := gin.Default()
v1 := r.Group("/v1", baseMid)
{
v1.GET("/login", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "Success")
})
}
r.Run(":80")
}
// or v1.Use(baseMid)
全局:
func main() {
r := gin.Default()
r.Use(baseMid)
v1 := r.Group("/v1")
{
v1.GET("/login", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "Success")
})
}
r.Run(":80")
}
2.3 Next()和Abort()
Next()
可以先执行Control
的内容,再返回到Next()
处:
func baseMid(ctx *gin.Context) {
fmt.Println("我进入了")
ctx.Next()
fmt.Println("我离开了")
}
func main() {
r := gin.Default()
r.Use(baseMid)
r.GET("/", func(ctx *gin.Context) {
fmt.Println("我显示了")
ctx.String(http.StatusOK, "Success")
})
r.Run(":80")
}
Abort()
可以结束Controller
的行为:
func baseMid(ctx *gin.Context) {
fmt.Println("我进入了")
ctx.Abort()
fmt.Println("我离开了")
}
func main() {
r := gin.Default()
r.Use(baseMid)
r.GET("/", func(ctx *gin.Context) {
fmt.Println("我显示了")
ctx.String(http.StatusOK, "Success")
})
r.Run(":80")
}
2.4 多中间件顺序
func Mid1(ctx *gin.Context) {
fmt.Println("中间件1进入")
ctx.Next()
fmt.Println("中间件1离开")
}
func Mid2(ctx *gin.Context) {
fmt.Println("中间件2进入")
ctx.Next()
fmt.Println("中间件2离开")
}
func main() {
r := gin.Default()
r.Use(Mid1, Mid2)
r.GET("/", func(ctx *gin.Context) {
fmt.Println("我显示了")
ctx.String(http.StatusOK, "Success")
})
r.Run(":80")
}
/*
中间件1进入
中间件2进入
我显示了
中间件2离开
中间件1离开
*/
func Mid1(ctx *gin.Context) {
fmt.Println("中间件1进入")
ctx.Abort()
fmt.Println("中间件1离开")
}
func Mid2(ctx *gin.Context) {
fmt.Println("中间件2进入")
ctx.Next()
fmt.Println("中间件2离开")
}
func main() {
r := gin.Default()
r.Use(Mid1, Mid2)
r.GET("/", func(ctx *gin.Context) {
fmt.Println("我显示了")
ctx.String(http.StatusOK, "Success")
})
r.Run(":80")
}
/*
中间件1进入
中间件1离开
*/
2.5 中间件与Control共享数据
可以用set*
和get*
等函数,例如:
func Mid1(ctx *gin.Context) {
ctx.Set("uid", "kanna")
}
func main() {
r := gin.Default()
r.Use(Mid1)
r.GET("/", func(ctx *gin.Context) {
uid := ctx.GetString("uid")
ctx.String(http.StatusOK, uid)
})
r.Run(":80")
}