配置
配置代理和安装gin包
- go env -w GO111MODULE=on
- go env -w GOPROXY=https://goproxy.io,direct
- 安装 gin 包 go get -u github.com/gin-gonic/gin
将 gin 引入到代码中:
1
| import "github.com/gin-gonic/gin"
|
第一个Gin程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
import ( "github.com/gin-gonic/gin" "net/http" )
func main() { r := gin.Default()
r.GET("/hello", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "hello world!", }) })
r.Run() }
|
html渲染
引入静态文件
1
| r.Static("/static", "./statics")
|
1
| <link rel="stylesheet" href="/static/index.css">
|
1
| <script src="/static/index.js"></script>
|
解析模板文件(在此之前可以自定义模板函数)
Gin框架中使用LoadHTMLGlob()
或者LoadHTMLFiles()
方法进行HTML模板渲染。
1 2 3
| r.LoadHTMLFiles("templates/index.tmpl") r.LoadHTMLGlob("templates/**/*")
|
模板渲染
1 2 3 4
| c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ "title": "贾某某", })
|
一个栗子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package main
import ( "github.com/gin-gonic/gin" "html/template" "net/http" )
func main() { r := gin.Default() r.Static("/static", "./statics") r.SetFuncMap(template.FuncMap{ "safe": func(str string) template.HTML { return template.HTML(str) }, })
r.LoadHTMLGlob("templates/**/*")
r.GET("/posts/index", func(c *gin.Context) { c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ "title": "贾某某", }) }) r.GET("/users/index", func(c *gin.Context) { c.HTML(http.StatusOK, "users/index.tmpl", gin.H{ "title": "<a href='https://jpcly.top'>贾小白</a>", }) })
r.Run(":9090") }
|
gin框架返回JSON
gin.H{}
其实就是map,我们可以将数据封装成map然后再序列化发送给前端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package main
import ( "github.com/gin-gonic/gin" "net/http" )
func main() { r := gin.Default()
r.GET("/aJSON", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "hello world!", }) })
type User struct { Name string `json:"name"` Gender string `json:"gender"` Age int `json:"age"` }
r.GET("/bJSON", func(c *gin.Context) { data := User{ Name: "梅西", Gender: "男", Age: 36, } c.JSON(http.StatusOK, data) })
r.Run() }
|
获取参数
get获取url参数
1 2 3 4 5 6 7 8 9
| r.GET("/index", func(c *gin.Context) { username := c.DefaultQuery("username", "jpc") address := c.Query("address") c.JSON(http.StatusOK, gin.H{ "message": "ok", "username": username, "address": address, }) })
|
运行结果
获取表单参数
main.go
文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| r.GET("/index2", func(c *gin.Context) { c.HTML(http.StatusOK, "index2.html", nil) })
r.POST("/index2", func(c *gin.Context) { username := c.PostForm("username") password := c.PostForm("password") c.JSON(http.StatusOK, gin.H{ "msg": "ok", "username": username, "password": password, }) })
|
index2.html
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/index2" method="post"> <label for="username">username:</label> <input type="text" name="username" id="username"> <br> <label for="password">password:</label> <input type="password" name="password" id="password"> <br> <input type="submit" value="登录"> </form> </body> </html>
|
运行结果
获取url路径参数
main.go
文件
1 2 3 4 5 6 7 8 9 10
| r.GET("/user/:username/:address", func(c *gin.Context) { username := c.Param("username") address := c.Param("address") c.JSON(http.StatusOK, gin.H{ "message": "ok", "username": username, "address": address, }) })
|
参数绑定
ShouldBind()
能够基于请求自动提取JSON
、form表单
和QueryString
类型的数据,并把值绑定到指定的结构体对象。
下面的例子是提取quertstring数据绑定到制定的结构体对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package main
import ( "github.com/gin-gonic/gin" "net/http" )
type Login struct { User string `form:"user" json:"user" binding:"required"` Password string `form:"password" json:"password" binding:"required"` }
func main() { router := gin.Default()
router.GET("/loginForm", func(c *gin.Context) { var login Login if err := c.ShouldBind(&login); err == nil { c.JSON(http.StatusOK, gin.H{ "user": login.User, "password": login.Password, }) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } })
router.Run(":9090") }
|
运行结果
请求重定向
HTTP 重定向很容易。 内部、外部重定向均支持。
1 2 3
| r.GET("/test", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "http://www.google.com/") })
|
路由重定向,使用 HandleContext
:
1 2 3 4 5 6 7
| 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"}) })
|
路由和路由组
路由参数
404界面
1 2 3
| r.NoRoute(func(c *gin.Context) { c.HTML(http.StatusNotFound, "views/404.html", nil) })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| func main() { router := gin.Default()
router.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") c.String(http.StatusOK, "Hello %s", name) })
router.GET("/user/:name/*action", func(c *gin.Context) { name := c.Param("name") action := c.Param("action") message := name + " is " + action c.String(http.StatusOK, message) })
router.Run(":8080") }
|
路由组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| func main() { router := gin.Default()
v1 := router.Group("/v1") { v1.POST("/login", loginEndpoint) v1.POST("/submit", submitEndpoint) v1.POST("/read", readEndpoint) }
v2 := router.Group("/v2") { v2.POST("/login", loginEndpoint) v2.POST("/submit", submitEndpoint) v2.POST("/read", readEndpoint) }
router.Run(":8080") }
|