文章目錄
-
- 一、重點内容:
-
- 知識要點有哪些?
-
- 1、Gin參數的擷取
- 2、Gin路由組
- 3、Gin中間件
- 4、Gin重定向和404
- 二、詳細知識點介紹:
-
- 1、接上一篇的代碼準備
-
- 代碼:
- 2、路由參數擷取
-
- 方式一:
-
- 代碼:
- 測試:
- 方式二:
-
- 代碼:
- 測試:
- 3、Json資料接收
-
- 代碼:
- 測試:
- 4、表單資料接收
-
- 代碼:
- 測試:
- 5、重定向
-
- 代碼:
- 測試:
- 6、404頁面
-
- 代碼:
- 測試:
- 7、路由群組
-
- 代碼:
- 測試:
- 8、中間件
-
- 分類使用方式
- 自定義中間件:
-
- 代碼:
- 測試:
- 9、控制器
- 三、課後個人總結:
一、重點内容:
知識要點有哪些?
1、Gin參數的擷取
2、Gin路由組
3、Gin中間件
4、Gin重定向和404
二、詳細知識點介紹:
1、接上一篇的代碼準備
以下是建立連接配接和加載資源的代碼:
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
2、路由參數擷取
方式一:
url:
http//:localhost:8082/info/id/name
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
//url:`http//:localhost:8082/info/id/name`
ginServer.GET("/info/:id/:name", func(context *gin.Context) {
id := context.Param("id")
name := context.Param("name")
context.JSON(http.StatusOK, gin.H{
"id": id,
"name": name,
})
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
方式二:
url:
http//:localhost:8082/info?id=111&name=xiaohua
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
//url:`http//:localhost:8082/info?id=111&name=xiaohua``
ginServer.GET("/info", func(context *gin.Context) {
id := context.Query("id")
name := context.Query("name")
context.JSON(http.StatusOK, gin.H{
"id": id,
"name": name,
})
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
3、Json資料接收
接收前端發送的Json資料并顯示:
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
//JSON資料
ginServer.POST("/json", func(context *gin.Context) {
data, _ := context.GetRawData()
var m map[string]interface{}
json.Unmarshal(data, &m)
context.JSON(http.StatusOK, m)
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
這裡使用APIpost工具測試post請求:
4、表單資料接收
接收前端發送的表單資料:
代碼:
html:(編寫表單)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>go web</title>
<!-- 連結 css和js-->
<link rel="stylesheet" href="../static/css/style.css">
<script src="../static/js/common.js"></script>
</head>
<body>
<h1>
Holle!!!
</h1>
表單:
<div class="myform">
<form action="/user/add" method="post">
<p> username: <input type="text" name="username" value="name"></p>
<p> password: <input type="password" name="password" value="password"></p>
<button type="submit">送出</button>
</form>
</div>
後端發送的消息:
{{.msg}}
{{.session}}
<img src="https://ts1.cn.mm.bing.net/th?id=ORMS.125d9efb147fe32b7990b8282e6bd509&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=0.9333299994468689&p=0">
</body>
</html>
go代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
ginServer.POST("/user/add", func(context *gin.Context) {
name := context.PostForm("username")
password := context.PostForm("password")
context.JSON(http.StatusOK, gin.H{
"msg": "ok",
"username": name,
"password": password,
})
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
送出後:
看到後端已經接收到資料了。
5、重定向
網頁開發中,常見網站搬移需要進行重定向:
代碼:
通路/redirect,重定向到首頁/index
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
ginServer.GET("/redirect", func(context *gin.Context) {
context.Redirect(http.StatusMovedPermanently, "/index")
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
6、404頁面
開發中十分常見的頁面,使用者通路url錯誤導緻:
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
ginServer.NoRoute(func(context *gin.Context) {
context.HTML(404, "404.html", nil)
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
建立一個響應的404.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 not found</title>
</head>
<body>
<h1>網頁走丢了!!!!</h1>
</body>
</html>
測試:
7、路由群組
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
routerGroup := ginServer.Group("/user")
{
routerGroup.GET("/login", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"login": "ok",
})
})
routerGroup.GET("/logout", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"logout": "ok",
})
})
}
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
8、中間件
分類使用方式
// 1.全局中間件
router.Use(gin.Logger())
router.Use(gin.Recovery())
// 2.單路由的中間件,可以加任意多個
router.GET("/benchmark", MyMiddelware(), benchEndpoint)
// 3.群組路由的中間件
authorized := router.Group("/", MyMiddelware())
// 或者這樣用:
authorized := router.Group("/")
authorized.Use(MyMiddelware())
{
authorized.POST("/login", loginEndpoint)
}
自定義中間件:
(傳輸全局session)
代碼:
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
"log"
"net/http"
)
/*
*
自定義中間件
*/
func myHandler() gin.HandlerFunc {
return func(context *gin.Context) {
context.Set("session", "ok")
context.Next()
// context.Abort()
}
}
func main() {
// 建立一個服務
ginServer := gin.Default()
// 使用圖示
ginServer.Use(favicon.New("./static/哔哩哔哩.png"))
// 加載html
ginServer.LoadHTMLGlob("templates/*")
// 加載靜态資源
ginServer.Static("/static", "./static")
ginServer.GET("/index", myHandler(), func(context *gin.Context) {
value, exists := context.MustGet("session").(string)
if !exists {
fmt.Println("找不到session")
}
fmt.Println("session:>>>>", value)
context.HTML(http.StatusOK, "index.html", gin.H{
"msg": "伺服器發送的html",
"session": value,
})
})
// 伺服器端口
err := ginServer.Run(":8082")
if err != nil {
log.Panicln(err)
return
}
}
測試:
9、控制器
- 資料解析綁定
模型綁定可以将請求體綁定給一個類型,目前支援綁定的類型有 JSON, XML 和标準表單資料 (foo=bar&boo=baz)。
要注意的是綁定時需要給字段設定綁定類型的标簽。比如綁定 JSON 資料時,設定
json:"fieldname"
。
使用綁定方法時,Gin 會根據請求頭中 Content-Type 來自動判斷需要解析的類型。如果你明确綁定的類型,你可以不用自動推斷,而用 BindWith 方法。
你也可以指定某字段是必需的。如果一個字段被
binding:"required"
修飾而值卻是空的,請求會失敗并傳回錯誤。
// Binding from JSON
type Login struct {
User string `form:"user" json:"user" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
}
func main() {
router := gin.Default()
// 綁定JSON的例子 ({"user": "manu", "password": "123"})
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
if c.BindJSON(&json) == nil {
if json.User == "manu" && json.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
}
})
// 綁定普通表單的例子 (user=manu&password=123)
router.POST("/loginForm", func(c *gin.Context) {
var form Login
// 根據請求頭中 content-type 自動推斷.
if c.Bind(&form) == nil {
if form.User == "manu" && form.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
}
})
// 綁定多媒體表單的例子 (user=manu&password=123)
router.POST("/login", func(c *gin.Context) {
var form LoginForm
// 你可以顯式聲明來綁定多媒體表單:
// c.BindWith(&form, binding.Form)
// 或者使用自動推斷:
if c.Bind(&form) == nil {
if form.User == "user" && form.Password == "password" {
c.JSON(200, gin.H{"status": "you are logged in"})
} else {
c.JSON(401, gin.H{"status": "unauthorized"})
}
}
})
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
三、課後個人總結:
這節課接着上節課,完備的學習了Gin架構的常見使用方式,并一一實踐,收獲頗豐。