Summary of knowledge points such as Golang GinWeb framework redirection / custom middleware / authentication / HTTPS support / elegant restart
这篇文章主要讲解了"Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结"吧!
重定向
Gin返回一个HTTP重定向非常简单, 使用Redirect方法即可. 内部和外部链接都支持.
package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { r := gin.Default() r.GET("/test", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "http://www.google.com/") //重定向到外部链接 }) //重定向到内部链接 r.GET("/internal", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "/home") }) r.GET("/home", func(c *gin.Context) { c.JSON(200, gin.H{"msg": "这是首页"}) }) r.Run(":8080") } /* 重定向到外部链接,访问:http://localhost:8080/test 重定向到内部链接,访问:http://localhost:8080/internal */
从POST方法中完成HTTP重定向, 参考问题#444 https://github.com/gin-gonic/gin/issues/444
r.POST("/test", func(c *gin.Context) { c.Redirect(http.StatusFound, "/foo") })
如果要产生一个路由重定向, 类似上面的内部重定向, 则使用 HandleContext方法, 像下面这样使用:
r.GET("/test", func(c *gin.Context) { c.Request.URL.Path = "/test2" r.HandleContext(c) }) r.GET("/test2", func(c *gin.Context) { c.JSON(200, gin.H{"hello": "world"}) })
自定义中间件
package main import ( "github.com/gin-gonic/gin" "log" "time" ) //自定义日志中间件 func Logger() gin.HandlerFunc { return func(c *gin.Context) { t := time.Now() // Set example variable 在gin上下文中设置键值对 c.Set("example", "12345") // before request //Next方法只能用于中间件中,在当前中间件中, 从方法链执行挂起的处理器 c.Next() // after request 打印中间件执行耗时 latency := time.Since(t) log.Print(latency) // access the status we are sending 打印本中间件的状态码 status := c.Writer.Status() log.Println(status) } } func main() { r := gin.New() //使用该自定义中间件 r.Use(Logger()) r.GET("/test", func(c *gin.Context) { example := c.MustGet("example").(string) //从上下文中获取键值对 // it would print: "12345" log.Println(example) }) // Listen and serve on 0.0.0.0:8080 r.Run(":8080") }
使用基本认证BasicAuth()中间件
package main import ( "github.com/gin-gonic/gin" "net/http" ) // simulate some private data var secrets = gin.H{ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"}, "austin": gin.H{"email": "austin@example.com", "phone": "666"}, "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"}, } func main() { r := gin.Default() // Group using gin.BasicAuth() middleware // gin.Accounts is a shortcut for map[string]string // 路由组authorized使用基本认证中间件, 参数为gin.Accounts,是一个map,键名是用户名, 键值是密码, 该中间件会将认证信息保存到cookie中 authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{ "foo": "bar", "austin": "1234", "lena": "hello2", "manu": "4321", })) // /admin/secrets endpoint // hit "localhost:8080/admin/secrets authorized.GET("/secrets", func(c *gin.Context) { // get user, it was set by the BasicAuth middleware // 从cookie中获取用户认证信息, 键名为user user := c.MustGet(gin.AuthUserKey).(string) if secret, ok := secrets[user]; ok { c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret}) } else { c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("}) } }) // Listen and serve on 0.0.0.0:8080 r.Run(":8080") } /* 测试访问:http://localhost:8080/admin/secrets */
在中间件中使用协程Goroutines
在中间件或者控制器中启动新协程时, 不能直接使用原来的Gin上下文, 必须使用一个只读的上下文副本
package main import ( "github.com/gin-gonic/gin" "log" "time" ) func main() { r := gin.Default() r.GET("/long_async", func(c *gin.Context) { // create copy to be used inside the goroutine // 创建一个Gin上下文的副本, 准备在协程Goroutine中使用 cCp := c.Copy() go func() { // simulate a long task with time.Sleep(). 5 seconds // 模拟长时间任务,这里是5秒 time.Sleep(5 * time.Second) // note that you are using the copied context "cCp", IMPORTANT // 在中间件或者控制器中启动协程时, 不能直接使用原来的上下文, 必须使用一个只读的上线文副本 log.Println("Done! in path " + cCp.Request.URL.Path) }() }) r.GET("/long_sync", func(c *gin.Context) { // simulate a long task with time.Sleep(). 5 seconds time.Sleep(5 * time.Second) // since we are NOT using a goroutine, we do not have to copy the context // 没有使用协程时, 可以直接使用Gin上下文 log.Println("Done! in path " + c.Request.URL.Path) }) // Listen and serve on 0.0.0.0:8080 r.Run(":8080") } /* 模拟同步阻塞访问:http://localhost:8080/long_sync 模拟异步非阻塞访问:http://localhost:8080/long_async */
自定义HTTP配置
直接使用 http.ListenAndServe()方法:
func main() { router := gin.Default() http.ListenAndServe(":8080", router) }
或者自定义HTTP配置
func main() { router := gin.Default() s := &http.Server{ Addr: ":8080", Handler: router, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1