天天看點

Go的web開發Gin架構2(九)—— Gin

文章目錄

    • 一、重點内容:
      • 知識要點有哪些?
        • 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
	}
}
           
測試:
Go的web開發Gin架構2(九)—— Gin

方式二:

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
	}
}
           
測試:
Go的web開發Gin架構2(九)—— Gin

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請求:

Go的web開發Gin架構2(九)—— Gin

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
	}
}
           

測試:

Go的web開發Gin架構2(九)—— Gin

送出後:

Go的web開發Gin架構2(九)—— Gin

看到後端已經接收到資料了。

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
	}
}
           

測試:

Go的web開發Gin架構2(九)—— Gin
Go的web開發Gin架構2(九)—— Gin

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>
           

測試:

Go的web開發Gin架構2(九)—— Gin

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
	}
}
           

測試:

Go的web開發Gin架構2(九)—— Gin
Go的web開發Gin架構2(九)—— Gin

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
	}
}
           
測試:
Go的web開發Gin架構2(九)—— Gin

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架構的常見使用方式,并一一實踐,收獲頗豐。