Salmon的全栈知识 Salmon的全栈知识
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Gin 介绍
  • Gin 环境搭建
  • golang 程序的热加载
  • Gin 框架中的路由
  • Gin HTML 模板渲染
  • 静态文件服务
  • 路由详解
    • 1、GET POST 以及获取 Get Post 传值
      • 1.1、Get 请求传值
      • 1.2、动态路由传值
      • 1.3、Post 请求传值 获取 form 表单数据
      • 1.4、获取 GET POST 传递的数据绑定到结构体
      • 1.5、获取 Post Xml 数据
    • 2、简单的路由组
    • 3、Gin 路由文件分组
      • 3.1、新建 routes 文件夹
      • 3.2 、配置 main.go
  • Gin 中自定义控制器
  • Gin 中间件
  • Gin 中自定义 Model
  • Gin 文件上传
  • Gin 中的 Cookie
  • Gin 中的 Session
  • Gin 中使用 GORM 操作 mysql 数据库
  • 原生 SQL 和 SQL 生成器
  • Gin 中使用 GORM 实现表关联查询
  • GORM 中使用事务
  • Gin 中使用 go-ini 加载.ini 配置文件
  • 《Gin》笔记
Salmon
2025-04-03
目录

路由详解

路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。

前面章节我们给大家介绍了路由基础以及路由配置,这里我们详细给大家讲讲路由传值、路由返回值。

# 1、GET POST 以及获取 Get Post 传值

# 1.1、Get 请求传值

GET /user?uid=20&page=1

router.GET("/user", func(c *gin.Context) {
    uid := c.Query("uid")
    page := c.DefaultQuery("page", "0")
    c.String(200, "uid=%v page=%v", uid, page)
})

# 1.2、动态路由传值

域名/user/20

router.GET("/user/:uid", func(c *gin.Context) {
    uid := c.Param("uid")
    c.String(200, "userID=%s", uid)
})

# 1.3、Post 请求传值 获取 form 表单数据

定义一个 add_user.html 的页面

{{ define "default/add_user.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<form action="/doAddUser" method="post">
    用户名:<input type="text" name="username" />
    密码: <input type="password" name="password" />
    <input type="submit" value="提交">
</form>
</body>
</html>
{{end}}

通过 c.PostForm 接收表单传过来的数据

package main

import "github.com/gin-gonic/gin"

func main() {
	router := gin.Default()
	//加载模板
	router.LoadHTMLGlob("templates/**/*")
	router.GET("/addUser", func(c *gin.Context) {
		c.HTML(200, "default/add_user.html", gin.H{})
	})
	router.POST("/doAddUser", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.PostForm("password")
		age := c.DefaultPostForm("age", "20")
		c.JSON(200, gin.H{"usernmae": username, "password": password, "age": age})
	})

	router.Run(":9090")
}

效果:

image-20250403143843458

image-20250403143952733

# 1.4、获取 GET POST 传递的数据绑定到结构体

为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的 Content-Type 识别请求数据类型并利用反射机制自动提取请求中 QueryString、form 表单、JSON、XML 等参数到结构体中。

下面的示例代码演示了.ShouldBind()强大的功能,它能够基于请求自动提取 JSON、form 表单和 QueryString 类型的数据,并把值绑定到指定的结构体对象。

// Userinfo 注意首字母大写
type Userinfo struct {
	Username string `form:"username" json:"user"`
	Password string `form:"password" json:"password"`
}

Get 传值绑定到结构体:/?username=zhangsan&password=123456

router.GET("/", func(c *gin.Context) {
    var userinfo Userinfo
    if err := c.ShouldBind(&userinfo); err == nil {
       c.JSON(http.StatusOK, userinfo)
    } else {
       c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    }
})

效果:

image-20250403144600493

Post 传值绑定到结构体

router.POST("/doLogin", func(c *gin.Context) {
    var userinfo Userinfo
    if err := c.ShouldBind(&userinfo); err == nil {
       c.JSON(http.StatusOK, userinfo)
    } else {
       c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    }
})

效果如下:

image-20250403145000267

# 1.5、获取 Post Xml 数据

在 API 的开发中,我们经常会用到 JSON 或 XML 来作为数据交互的格式,这个时候我们可以在 gin 中使用 c.GetRawData() 获取数据。

<?xml version="1.0" encoding="UTF-8"?>
<article>
    <content type="string">我是张三</content>
    <title type="string">张三</title>
</article>

代码:

package main

import (
    "encoding/xml"
    "github.com/gin-gonic/gin"
    "net/http"
)

type Article struct {
    Title   string `xml:"title"`
    Content string `xml:"content"`
}

func main() {
    router := gin.Default()
    router.POST("/xml", func(c *gin.Context) {
       b, _ := c.GetRawData() // 从 c.Request.Body 读取请求数据
       article := &Article{}
       if err := xml.Unmarshal(b, &article); err == nil {
          c.JSON(http.StatusOK, article)
       } else {
          c.JSON(http.StatusBadRequest, err.Error())
       }
    })

    router.Run(":9090")
}

效果:

image-20250403145503150

# 2、简单的路由组

文档:https://gin-gonic.com/zh-cn/docs/examples/grouping-routes/ (opens new window)

package main

import "github.com/gin-gonic/gin"

func main() {
    router := gin.Default()
    // 简单的路由组: v1
    v1 := router.Group("/v1")
    {
       v1.POST("/login", loginEndpoint)
       v1.POST("/submit", submitEndpoint)
       v1.POST("/read", readEndpoint)
    }
    // 简单的路由组: v2
    v2 := router.Group("/v2")
    {
       v2.POST("/login", loginEndpoint)
       v2.POST("/submit", submitEndpoint)
       v2.POST("/read", readEndpoint)
    }
    router.Run(":8080")
}

# 3、Gin 路由文件分组

# 3.1、新建 routes 文件夹

routes 文件下面新建 adminRoutes.go、apiRoutes.go、defaultRoutes.go

1、新建 adminRoutes.go

package routes

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func AdminRoutesInit(router *gin.Engine) {
    adminRouter := router.Group("/admin")
    {
       adminRouter.GET("/user", func(c *gin.Context) {
          c.String(http.StatusOK, "用户")
       })
       adminRouter.GET("/news", func(c *gin.Context) {
          c.String(http.StatusOK, "news")
       })
    }
}

2、新建 apiRoutes.go

func ApiRoutesInit(router *gin.Engine) {
    apiRoute := router.Group("/api")
    {
       apiRoute.GET("/user", func(c *gin.Context) {
          c.JSON(http.StatusOK, gin.H{
             "username": "张三",
             "age":      20,
          })
       })
       apiRoute.GET("/news", func(c *gin.Context) {
          c.JSON(http.StatusOK, gin.H{
             "title": "这是新闻",
          })
       })
    }
}

3、新建 defaultRoutes.go

package routes

import (
    "github.com/gin-gonic/gin"
)

func DefaultRoutesInit(router *gin.Engine) {
    defaultRoute := router.Group("/")
    {
       defaultRoute.GET("/", func(c *gin.Context) {
          c.String(200, "首页")
       })
    }
}

# 3.2 、配置 main.go

package main

import (
    "github.com/gin-gonic/gin"
    "test4/routes"
)

// Userinfo 注意首字母大写
type Userinfo struct {
    Username string `form:"username" json:"user"`
    Password string `form:"password" json:"password"`
}

func main() {
    r := gin.Default()
    routes.AdminRoutesInit(r)
    routes.ApiRoutesInit(r)
    routes.DefaultRoutesInit(r)
    r.Run(":9090")
}

效果:

image-20250403151734014

上次更新: 2025/04/03, 16:12:12
静态文件服务
Gin 中自定义控制器

← 静态文件服务 Gin 中自定义控制器→

Theme by Vdoing | Copyright © 2022-2025 Salmon's Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式