Go的web开发Gin框架2(九)—— Gin

一、重点内容:

知识要点有哪些?

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
	}
}
测试:
image-20230214231538860

方式二:

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
	}
}
测试:
image-20230214232011306

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

image-20230214232705922

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

测试:

image-20230214233115802

提交后:

image-20230214233148233

看到后端已经接收到数据了。

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

测试:

image-20230214233503530 image-20230214233519062

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>

测试:

image-20230214233836842

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

测试:

image-20230214234105391 image-20230214234128478

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
	}
}
测试:

image-20230214234452898

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框架的常见使用方式,并一一实践,收获颇丰。

猜你喜欢

转载自blog.csdn.net/qq_54353206/article/details/129035573