一. Controller
用不同的Controller
可以实现业务的分类,不同类型的请求可以共用同一套中间件
1.1 单文件Controller
几乎等同于函数封装,直接将ctrl
的代码写入到一个文件里然后调用:
package adminimport ("net/http""github.com/gin-gonic/gin"
)func Index(ctx *gin.Context) {ctx.String(http.StatusOK, "首页")
}
调用:
package mainimport ("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 adminimport ("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 mainimport ("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")
}