Gin
下载gin框架
go get -u github.com/gin-gonic/gin
下载失败的话配置一下goproxy
关闭GOSUMDB
go env -w GOSUMDB=off
更换源
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
下载后,再执行代码可能可能会报,binding.go文件中any,undefined any
尝试将Gin框架更新到最新版本
go get -u github.com/gin-gonic/gin
如果问题仍然存在,切换到稳定的版本,再go.mod文件中指定版本
require github.com/gin-gonic/gin v1.6.3
案例
下载go get github.com/thinkerou/favicon
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
import "github.com/thinkerou/favicon"
func main() {
// 创建服务
ginServer := gin.Default()
// 修改图标
ginServer.Use(favicon.New("./火影忍者.png"))
// 访问地址
ginServer.GET("/hello", func(context *gin.Context) {
context.JSON(200, gin.H{"msg": "Hello Wold"})
})
ginServer.POST("/user", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{"msg": "post"})
})
// 服务器端口
ginServer.Run(":8082")
}
获取参数
获取querystring参数
querystring指的是URL中?后面携带的参数,例如:/user/search?username=小王子&address=沙河。 获取请求的querystring参数的方法如下:
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.GET("/user/search", func(c *gin.Context) {
// 可以添加默认值
username := c.DefaultQuery("username", "小王子")
//username := c.Query("username")
address := c.Query("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
r.Run()
}
获取form参数
请求的数据通过form表单来提交,例如向/user/search发送一个POST请求,获取请求数据的方式如下:
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.POST("/user/search", func(c *gin.Context) {
// DefaultPostForm取不到值时会返回指定的默认值
//username := c.DefaultPostForm("username", "小王子")
username := c.PostForm("username")
address := c.PostForm("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
r.Run(":8080")
}
获取path参数
请求的参数通过URL路径传递,例如:/user/search/小王子/沙河。 获取请求URL路径中的参数的方式如下。
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.GET("/user/search/:username/:address", func(c *gin.Context) {
username := c.Param("username")
address := c.Param("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
r.Run(":8080")
}
参数绑定
func main() {
// 创建服务
ginServer := gin.Default()
ginServer.Use(favicon.New("./火影忍者.png"))
type Login struct {
User string `form:"user"`
Password string `form:"password"`
}
// 绑定JSON的示例 ({"user": "q1mi", "password": "123456"})
ginServer.POST("/loginJSON", func(context *gin.Context) {
var login Login
if err := context.ShouldBindJSON(&login); err == nil {
fmt.Printf("login info:%v\n", login)
context.AbortWithStatusJSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
context.AbortWithStatusJSON(http.StatusBadRequest, err.Error())
}
})
// 绑定form表单示例 (user=q1mi&password=123456)
ginServer.POST("/loginForm", func(context *gin.Context) {
var login Login
if err := context.ShouldBind(&login); err == nil {
fmt.Printf("login info:%v\n", login)
context.AbortWithStatusJSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
context.AbortWithStatusJSON(http.StatusBadRequest, err.Error())
}
})
// 绑定QueryString示例 (/loginQuery?user=q1mi&password=123456)
ginServer.GET("/loginForm", func(context *gin.Context) {
var login Login
if err := context.ShouldBindQuery(&login); err == nil {
fmt.Printf("login info:%v\n", login)
context.AbortWithStatusJSON(http.StatusOK, gin.H{
"user": login.User,
"password": login.Password,
})
} else {
context.AbortWithStatusJSON(http.StatusBadRequest, err.Error())
}
})
ginServer.Run(":8082")
}
重定向
HTTP重定向
r.GET("/test", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/")
})
路由重定向
r.GET("/test", func(c *gin.Context) {
// 指定重定向的URL
c.Request.URL.Path = "/test2"
r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"hello": "world"})
})
中间件
定义中间件
// StatCost 是一个统计耗时请求耗时的中间件
func StatCost() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Set("name", "小王子") // 可以通过c.Set在请求上下文中设置值,后续的处理函数能够取到该值
// 调用该请求的剩余处理程序
c.Next()
// 不调用该请求的剩余处理程序
// c.Abort()
// 计算耗时
cost := time.Since(start)
log.Println(cost)
}
}
注册中间件
为全局路由注册
func main() {
// 新建一个没有任何默认中间件的路由
r := gin.New()
// 注册一个全局中间件
r.Use(StatCost())
r.GET("/test", func(c *gin.Context) {
name := c.MustGet("name").(string) // 从上下文取值
log.Println(name)
c.JSON(http.StatusOK, gin.H{
"message": "Hello world!",
})
})
r.Run()
}
为某个路由单独组测
// 给/test2路由单独注册中间件(可注册多个)
r.GET("/test2", StatCost(), func(c *gin.Context) {
name := c.MustGet("name").(string) // 从上下文取值
log.Println(name)
c.JSON(http.StatusOK, gin.H{
"message": "Hello world!",
})
})
为路由组注册
shopGroup := r.Group("/shop", StatCost())
{
shopGroup.GET("/index", func(c *gin.Context) {...})
...
}
shopGroup := r.Group("/shop")
shopGroup.Use(StatCost())
{
shopGroup.GET("/index", func(c *gin.Context) {...})
...
}