• Gin路由基础


    Gin路由基础

    1 路由的基本使

    • gin 框架中采用的路由库是基于httprouter做的
    • 地址为:https://github.com/julienschmidt/httprouter

    1.1 基本路由

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func funcPost(c *gin.Context)  {
    	c.String(http.StatusOK, "post请求")
    }
    func main() {
    	r := gin.Default()
    	r.GET("/", func(c *gin.Context) {
    		c.String(http.StatusOK, "hello word")
    	})
    	r.POST("/",funcPost)
    	//r.DELETE()
    	//r.PUT()
    	//r.OPTIONS()
    	
    	//监听端口默认为8080
    	r.Run(":8000")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    1.2 获取路径中参数(动态路由)

    • 可以通过Context的Param方法来获取API参数
    • localhost:8000/user/lxx/nb
    • /:name表示一个字符串或int类型
    • /*action表示任意字符串,包括/,如 /nb/hadsome,*号类型的参数,表示匹配所有
    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"strings"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/user/:name/*action", func(c *gin.Context) {
    		name := c.Param("name")
    		action := c.Param("action")
    		fmt.Println(action)
    		//把字符串开头/截取掉
    		action = strings.Trim(action, "/")
    		fmt.Println(action)
    		c.String(http.StatusOK, name+" is "+action)
    	})
    	//默认为监听8080端口
    	r.Run(":8000")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    1.3 获取请求地址中参数

    • URL参数可以通过DefaultQuery()或Query()方法获取
    • DefaultQuery()若参数不存在,返回默认值,Query()若不存在,返回空串
    • API http://localhost:8080/user?name=lxx
    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/user", func(c *gin.Context) {
    		//指定默认值
    		//http://localhost:8080/user 才会打印出来默认的值
    		//name := c.DefaultQuery("name", "世界")
    		name := c.Query("name")
    		c.String(http.StatusOK, fmt.Sprintf("hello %s", name))
    	})
    	r.Run()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.4 获取表单参数

    • 表单传输为post请求,http常见的传输格式为四种:
      • application/json
      • application/x-www-form-urlencoded
      • application/xml
      • multipart/form-data
    • 表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencoded或from-data格式的参数
    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.POST("/form", func(c *gin.Context) {
    		username := c.PostForm("username")
    		password := c.PostForm("password")
    		// 获取body体中数据--》json格式
    		body,_ := ioutil.ReadAll(c.Request.Body)
    		fmt.Println("---body--"+string(body))
    		c.String(http.StatusOK, fmt.Sprintf("用户名:%s,密码:%s", username, password))
    	})
    	r.Run()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1.5 Json 编码格式解析到结构体

    客户端传参,后端接收并解析到结构体定

    把对应的数据解析好结构体中,需要在结构体中配置相应的配置,才能正常使用ShouldBind系列方法

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    // 定义接收数据的结构体
    type Login struct {
    	// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
    	User    string `json:"username" binding:"required"`
    	Password string `json:"password" binding:"required"`
    }
    
    func main() {
    	// 1.创建路由
    	r := gin.Default()
    	// JSON绑定
    	r.POST("/loginJSON", func(c *gin.Context) {
    		// 声明接收的变量
    		var login Login
    		// 将request的body中的数据,自动按照json格式解析到结构体(只能解析json格式)
    		if err := c.ShouldBindJSON(&login); err != nil {
    			// 返回错误信息
    			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    			return
    		}
    		// 判断用户名密码是否正确
    		if login.User == "lxx" && login.Password == "123" {
    			c.JSON(http.StatusBadRequest, gin.H{"status": "100", "msg": "登陆成功"})
    		}else {
    			c.JSON(http.StatusOK, gin.H{"status": "101","msg": "用户名或密码错误"})
    		}
    
    	})
    	r.Run(":8000")
    }
    
    • 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

    1.6 urlencoded和form-data编码格式解析到结构体

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    // 定义接收数据的结构体
    type Login struct {
    	// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
    	User    string `form:"username" binding:"required"`
    	Password string `form:"password" binding:"required"`
    }
    
    func main() {
    	// 1.创建路由
    	r := gin.Default()
    	// JSON绑定
    	r.POST("/loginForm", func(c *gin.Context) {
    		// 声明接收的变量
    		var login Login
    		//Bind()默认解析并绑定form格式,根据请求头中content-type自动推断
    		//urlencoded,json,form-data格式都支持
    		if err := c.Bind(&login); err != nil {
    			// 返回错误信息
    			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    			return
    		}
    		// 判断用户名密码是否正确
    		if login.User == "lxx" && login.Password == "123" {
    			c.JSON(http.StatusBadRequest, gin.H{"status": "100", "msg": "登陆成功"})
    		}else {
    			c.JSON(http.StatusOK, gin.H{"status": "101","msg": "用户名或密码错误"})
    		}
    
    	})
    	r.Run(":8000")
    }
    
    • 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

    1.7 动态路由数据解析到结构体

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    // 定义接收数据的结构体
    type Login struct {
    	User    string `uri:"username"  binding:"required"`
    	Password string `uri:"password" binding:"required"`
    }
    
    func main() {
    	r := gin.Default()
    	r.GET("login/:username/:password", func(c *gin.Context) {
    		var login Login
    		// 解析并绑定路径中的参数
    		if err := c.ShouldBindUri(&login); err != nil {
    			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    			return
    		}
    		// 判断用户名密码是否正确
    		fmt.Println(login.Password,login.User)
    		if login.User != "lxx" || login.Password != "123" {
    			c.JSON(http.StatusBadRequest, gin.H{"status": "304", "msg": "用户名或密码错误"})
    			return
    		}
    		c.JSON(http.StatusOK, gin.H{"status": "200"})
    	})
    	r.Run(":8000")
    }
    
    • 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

    1.8 post或get提交数据解析到结构体

    ShouldBind会按照下面的顺序解析请求中的数据完成绑定:

    1. 如果是 GET 请求,http://127.0.0.1:8000/loginForm/?username=lxx&password=123
    2. 如果是 POST 请求,三种编码格式都支持
    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    // 定义接收数据的结构体
    type Login struct {
    	// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
    	User     string `form:"username" json:"username" uri:"username" binding:"required"`
    	Password string `form:"password" json:"password" uri:"password"  binding:"required"`
    }
    
    func main() {
    	router := gin.Default()
    	// 绑定JSON的示例 ({"username": "lxx", "password": "123"})
    	router.POST("/loginJSON", 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()})
    		}
    	})
    
    	// 绑定QueryString示例 (http://127.0.0.1:8000/loginForm/?username=lxx&password=123)
    	router.GET("/loginForm", func(c *gin.Context) {
    		var login Login
    		// ShouldBind()会根据请求的Content-Type自行选择绑定器
    		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(":8000")
    }
    
    • 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

    1.9 xml格式解析到结构体

    <?xml version="1.0" encoding="UTF-8"?> 
    <login>
    <username type="string">刘清政</username>
    <password type="string">123</password> 
    </login>
    
    package main
    
    import (
    	"encoding/xml"
    	"fmt"
    	"github.com/gin-gonic/gin"
    )
    
    // 定义接收数据的结构体
    type Login struct {
    	// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
    	User     string `xml:"username" binding:"required"`
    	Password string `xml:"password"  binding:"required"`
    }
    
    func main() {
    	router := gin.Default()
    	router.POST("/loginXml", func(c *gin.Context) {
    		var login Login
    		body,_:=c.GetRawData() // 本质就是从body中读出所有数据:ioutil.ReadAll(c.Request.Body)
    		err:=xml.Unmarshal(body,&login)
    		if err != nil {
    			fmt.Println(err)
    			c.String(200,"解析xml失败")
    			return
    		}
    
    		fmt.Println(login)
    		c.String(200,"解析xml成功")
    	})
    	router.Run(":8000")
    }
    
    • 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

    2 不使用默认中间件

    使用

    r := gin.New()
    
    • 1

    代替

    // Default 使用 Logger 日志中间件 和 Recovery 错误处理中间件
    r := gin.Default()
    
    // Default 源码
    debugPrintWARNINGDefault()  // 调试打印警告默认值
    engine := New()
    engine.Use(Logger(), Recovery()) // 使用中间件
    return engine
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    微电子专业深度盘点:哪所大学芯片最强?强在哪?(第3弹)
    Typora如何把图片上传到图床smms.app
    开发模型的特点对照表
    ClickHouse 数据类型、表引擎与TTL
    Java基础-反射
    【JDBC】JDBC的基本使用
    wpf使用CefSharp.OffScreen模拟网页登录,并获取身份cookie
    Flutter介绍
    [Java] 什么是IoC?什么是DI?它们的区别是什么?
    Golang协程的概念、用法、场景及案例
  • 原文地址:https://blog.csdn.net/qq_55752792/article/details/126330386