当项目比较大的时候有必要对控制器进行分组
在项目根目录下新建 controller ,在 controller 中新建 admin user … 文件夹
在 admin 文件当中新建 indexController.go userController.go文件
indexController.go
package admin
import "github.com/gin-gonic/gin"
type IndexController struct {
}
func (con IndexController) Index(c *gin.Context) {
c.String(200, "后台页面")
}
userController.go
package admin
import "github.com/gin-gonic/gin"
type UserController struct {
}
func (con UserController) Index(c *gin.Context) {
c.String(200, "用户列表")
}
func (con UserController) Add(c *gin.Context) {
c.String(200, "用户列表---add")
}
func (con UserController) Edit(c *gin.Context) {
c.String(200, "用户列表---edit")
}
routes 文件夹下
配置对应的路由—adminRoutes.go
package routes
import (
"Gin_demo/controllers/admin"
"github.com/gin-gonic/gin"
)
func AdminRoutesInit(r *gin.Engine) {
adminRoutes := r.Group("/admin")
{
adminRoutes.GET("/", admin.IndexController{}.Index)
adminRoutes.GET("/user", admin.UserController{}.Index)
adminRoutes.GET("/user/add", admin.UserController{}.Add)
adminRoutes.GET("/user/edit", admin.UserController{}.Edit)
}
}
1、新建 controller/admin/baseController.go
package admin
import "github.com/gin-gonic/gin"
type BaseController struct {
}
func (con BaseController) success(c *gin.Context) {
c.String(200, "成功")
}
func (con BaseController) error(c *gin.Context) {
c.String(200, "失败")
}
2、userController 继承 baseController
package admin
import "github.com/gin-gonic/gin"
type UserController struct {
BaseController
}
func (con UserController) Index(c *gin.Context) {
//c.String(200, "用户列表")
con.success(c)
}
func (con UserController) Add(c *gin.Context) {
c.String(200, "用户列表---add")
}
func (con UserController) Edit(c *gin.Context) {
c.String(200, "用户列表---edit")
}
中间件就是匹配路由前和匹配路由完成后执行的一系列操作
Gin 当中的中间件必须是一个 gin.HandlerFunc 类型,配置路由的时候可以传递多个 func 回调函数,最后一个 func 回调函数前面触发的函数都可以称为中间件。
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"time"
)
func InitMessage(c *gin.Context) {
fmt.Println("111")
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.Static("/static", "./static")
r.GET("/", InitMessage, func(c *gin.Context) {
c.String(200, "首页")
})
r.GET("/news", InitMessage, func(c *gin.Context) {
c.String(200, "新闻")
})
r.Run()
}
中间件中加上 c.Next() 可以让我们在路由匹配完成后执行一些操作
统计一个请求的执行时间
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"time"
)
func InitMessage(c *gin.Context) {
fmt.Println("111")
start := time.Now().Nanosecond()
// 调用该请求的剩余处理程序
c.Next()
end := time.Now().Nanosecond()
fmt.Println(end - start)
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.Static("/static", "./static")
r.GET("/", InitMessage, func(c *gin.Context) {
c.String(200, "首页")
})
r.GET("/news", InitMessage, func(c *gin.Context) {
c.String(200, "新闻")
})
r.Run()
}
当一个请求中存在多个中间件,其执行顺序又是如何呢?
可以在控制台中打印不同的信息来确定程序的执行顺序。
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func InitMiddlewareOne(c *gin.Context) {
fmt.Println("1")
// 调用该请求的剩余处理程序
c.Next()
fmt.Println("2")
}
func InitMiddlewareTwo(c *gin.Context) {
fmt.Println("3")
// 调用该请求的剩余处理程序
c.Next()
fmt.Println("4")
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.Static("/static", "./static")
r.GET("/", InitMiddlewareOne, InitMiddlewareTwo, func(c *gin.Context) {
fmt.Println("首页...")
c.String(200, "首页")
})
r.GET("/news", InitMiddlewareOne, InitMiddlewareTwo, func(c *gin.Context) {
c.String(200, "新闻")
})
r.Run()
}
控制台内容:
1
3
首页...
4
2
可以使用r.Use(中间件名称)
来定义全局中间件
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func InitMiddleware(c *gin.Context) {
fmt.Println("1")
// 调用该请求的剩余处理程序
c.Next()
fmt.Println("2")
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.Static("/static", "./static")
// 定义全局中间件
r.Use(InitMiddleware)
r.GET("/", func(c *gin.Context) {
fmt.Println("首页...")
c.String(200, "首页")
})
r.GET("/news", func(c *gin.Context) {
c.String(200, "新闻")
})
r.Run()
}
在项目根目录下新建 middlewares 文件夹,并新建中间件
package middlewares
import (
"fmt"
"github.com/gin-gonic/gin"
"time"
)
func InitMiddleware(c *gin.Context) {
fmt.Println(time.Now())
fmt.Println(c.Request.URL)
}
在 routes 文件中的路由文件使用中间件
package routes
import (
"Gin_demo/controllers/admin"
"Gin_demo/middlewares"
"github.com/gin-gonic/gin"
)
func AdminRoutesInit(r *gin.Engine) {
// 使用中间件
adminRoutes := r.Group("/admin", middlewares.InitMiddleware)
{
adminRoutes.GET("/", admin.IndexController{}.Index)
adminRoutes.GET("/user", admin.UserController{}.Index)
adminRoutes.GET("/user/add", admin.UserController{}.Add)
adminRoutes.GET("/user/edit", admin.UserController{}.Edit)
adminRoutes.GET("/article", admin.ArticleController{}.Index)
adminRoutes.GET("/article/add", admin.ArticleController{}.Add)
adminRoutes.GET("/article/edit", admin.ArticleController{}.Edit)
}
}
在中间件当中设置值
package middlewares
import (
"fmt"
"github.com/gin-gonic/gin"
"time"
)
func InitMiddleware(c *gin.Context) {
c.Set("username", "zhangsan")
}
在控制器当中获取值
package admin
import (
"fmt"
"github.com/gin-gonic/gin"
)
type UserController struct {
BaseController
}
func (con UserController) Index(c *gin.Context) {
//c.String(200, "用户列表")
//con.success(c)
username, _ := c.Get("username")
v, ok := username.(string)
if ok {
c.String(200, v)
} else {
c.String(200, "获取用户失败")
}
fmt.Println("username==>", username)
}
func (con UserController) Add(c *gin.Context) {
c.String(200, "用户列表---add")
}
func (con UserController) Edit(c *gin.Context) {
c.String(200, "用户列表---edit")
}
1、gin.Default() 默认使用了 Logger 和 Recovery 中间件,其中:
如果不想使用上面两个默认的中间件,可以使用 gin.New() 新建一个没有任何默认中间件的路由,一般情况下推荐使用 gin.Default() 。
2、当在中间件或 handler 中启动新的 goroutine 时,不能使用原始的上下文(c *gin.Context),必须使用其只读副本(c.Copy())
r.GET("/", func(c *gin.Context) {
cCp := c.Copy()
go func() {
// simulate a long task with time.Sleep(). 5 seconds
time.Sleep(5 * time.Second)
// 这里使用你创建的副本
fmt.Println("Done! in path " + cCp.Request.URL.Path)
}()
c.String(200, "首页")
})