当前位置: 首页 > article >正文

Gin从入门到精通 (三)路由

路由

在 Web 应用开发中,路由的作用是根据不同的 URL 请求,将其映射到相应的处理函数上,以实现不同的业务逻辑。Gin 框架提供了丰富且灵活的路由功能,使开发者能够轻松应对各种复杂的路由需求。

1. 基础路由

Gin 的路由处理非常直观,下面展示了一些基本的路由用法。

1.1 处理 GET 请求

GET方法请求一个指定资源的表示形式. 使用GET的请求应该只被用于获取数据.

r.GET("/hello", func(c *gin.Context) {
    c.String(200, "Hello, world!")
})

上述代码定义了一个简单的 GET 请求路由。当客户端向服务器发起对/hello路径的 GET 请求时,Gin 框架会捕获该请求,并执行对应的匿名函数。在该匿名函数中,通过c.Stri``ng(200, "``Hello, world!")向客户端返回 HTTP 状态码 200(表示请求成功),以及响应内容 “Hello, world!” 。

1.2 处理 POST 请求

POST方法用于将实体提交到指定的资源,通常会导致在服务器上的状态变化

package main

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

func main() {
	r := gin.Default()
	r.POST("/post", func(c *gin.Context) {
		var json struct {
			Name string `json:"name"`
			Age  int    `json:"age"`
		}
		if err := c.ShouldBindJSON(&json); err != nil {
			c.JSON(400, gin.H{"error": err.Error()})
			return
		}
		c.JSON(200, gin.H{"message": "Data received", "name": json.Name, "age": json.Age})
	})

	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

代码实现了对 POST 请求的处理。当接收到对/post路径的 POST 请求时,首先定义一个结构体json,用于存储从请求体中解析出来的 JSON 数据。然后使用c.ShouldBindJSON(&json)方法尝试将请求体中的 JSON 数据绑定到json结构体上。

如果绑定过程中出现错误,如请求体格式不正确,就会返回 HTTP 状态码 400(表示客户端请求错误),并将错误信息以 JSON 格式返回给客户端。若绑定成功,则返回 HTTP 状态码 200,以及包含成功消息和解析出的name字段和age字段的 JSON 数据。

1.3 处理 PUT 请求

PUT方法用请求有效载荷替换目标资源的所有当前表示

   // 处理 PUT 请求
    r.PUT("/update", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "PUT request received"})
    })

1.4 处理 DELETE 请求

  // 处理 DELETE 请求
   r.DELETE("/delete", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "DELETE request received"})
    })

2.处理动态路由参数

动态路由参数允许在 URL 中包含可变部分,这些部分可以在处理函数中获取。

package main

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

func main() {
	r := gin.Default()

	r.GET("/user/:id", func(c *gin.Context) {
		id := c.Param("id")
		c.String(200, "User ID: %s", id)
	})

	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}


代码展示了如何处理带有动态路由参数的请求。在路由定义中,/user/:id表示路径中的:id是一个动态参数。当客户端请求类似/user/123这样的路径时,Gin 框架会将123作为id参数的值。在处理函数中,通过c.Param("id")获取这个参数值,并将其作为响应内容的一部分返回给客户端,

请求路径:

http://localhost:8080/user/12

返回数据:

User ID: 123

3.多个动态路由参数

可以在一个路由中包含多个动态参数。


package main

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

func main() {
	r := gin.Default()
	r.GET("/user/:id/book/:book_id", func(c *gin.Context) {
		id := c.Param("id")
		bookID := c.Param("book_id")
		c.String(200, "User ID: %s, Book ID: %s", id, bookID)
	})

	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}


此示例展示了如何处理包含多个动态路由参数的请求。在/user/:id/book/:book_id这个路由中,有两个动态参数:id:book_id。当客户端请求如/user/1/book/5这样的路径时,1会被赋值给id5会被赋值给bookID

在处理函数中,分别通过c.Param("id")c.Param("book_id")获取这两个参数值,并将它们作为响应内容返回给客户端,即返回 “User ID: 1, Book ID: 5” 。

请求路径:

http://localhost:8080/1/5

返回数据:

User ID: 1, Book ID: 5

4.路由分组

Gin 允许开发者为路由创建分组,这在实际项目开发中非常实用。通过Group()方法,可以将相关的路由组织在一起,便于管理和维护,同时还能为不同的路由组添加特定的中间件。

package main

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

func main() {
	r := gin.Default()
	user := r.Group("/user")
	{
		user.GET("/info", func(c *gin.Context) {
			c.String(200, "user info")
		})
		user.GET("/login", func(c *gin.Context) {
			c.String(200, "user login")
		})

	}

	r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

上述代码创建了一个名为user的路由组,该路由组的所有路由都以/user为前缀。在这个路由组中,定义了两个 GET 请求路由:/user/info/user/login,分别返回 “user info” 和 “user login”。

此外,还可以在路由组中使用中间件,例如添加身份验证的中间件:

user := r.Group("/user", AuthMiddleware())

这样,当需要对这组路由进行统一管理或添加共同的中间件时,就可以直接在user路由组上进行操作,而无需对每个路由单独处理。

5.通配符路由

通配符路由可以匹配任意路径,使用 * 作为通配符。

package main

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

func main() {
	r := gin.Default()

	// 定义通配符路由
	r.GET("/static/*filepath", func(c *gin.Context) {
		// 获取通配符匹配的路径
		filepath := c.Param("filepath")
		c.String(200, "Static file path: %s", filepath)
	})

	r.Run(":8080")
}

此示例展示了通配符路由。*filepath 是通配符参数,它可以匹配 /static/ 后面的任意路径。

请求路径:

http://localhost:8080/static/c/go/bin

返回数据:

Static file path: /c/go/bin

6.NoRotu 处理 404 错误

当客户端请求的路径没有匹配到任何路由时,Gin 会返回 404 错误。可以自定义 404 错误处理函数。

package main

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

func main() {
	r := gin.Default()

	// 定义自定义的 404 错误处理函数
	r.NoRoute(func(c *gin.Context) {
		c.JSON(404, gin.H{"error": "Page not found"})
	})

	r.Run(":8080")
}

r.NoRoute 方法用于定义 404 错误处理函数,当请求的路径没有匹配到任何路由时,会执行该函数。

正常我们都是使用一个404页面来提示用户,我们可以用下面的方法来实现:

在项目中创建tpl目录,该目录下创建notpage.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>404 - Page Not Found</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            text-align: center;
            padding-top: 100px;
        }

        h1 {
            font-size: 60px;
            color: #333;
        }

        p {
            font-size: 20px;
            color: #666;
        }

        a {
            color: #007BFF;
            text-decoration: none;
        }

        a:hover {
            text-decoration: underline;
        }
    </style>
</head>

<body>
<h1>404</h1>
<p>Oops! The page you're looking for doesn't exist.</p>
<p>You can <a href="/">go back to the homepage</a> or try another search.</p>
</body>

</html>

修改mian.go:


package main

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

func main() {
	r := gin.Default()
	// 设置 HTML 模板文件的路径
	r.LoadHTMLGlob("tpl/*")
	// 定义自定义的 404 错误处理函数
	/*
		r.NoRoute(func(c *gin.Context) {
			c.JSON(404, gin.H{"error": "Page not found"})
		})
	*/

	r.NoRoute(func(c *gin.Context) {
		c.HTML(200, "notpage.html", gin.H{})
	})

	r.Run(":8080")
}

当执行任何不存在的路由就会返回以下页面

在这里插入图片描述

7.路由优先级

Gin 根据路由的定义顺序匹配请求的路径,较为精确的路径会先匹配。


http://www.kler.cn/a/559709.html

相关文章:

  • [特殊字符] 蓝桥杯 Java B 组 之位运算(异或性质、二进制操作)
  • 在生产环境中部署和管理 PostgreSQL:实战经验与最佳实践
  • 如何在java中用httpclient实现rpc get请求
  • java实现二维码图片生成和编解码
  • 关于 BK3633 上电时受串口 UART2 影响而无法启动的问题说明
  • git常用指令详解
  • SQL写法技巧
  • vllm部署LLM(qwen2.5,llama,deepseek)
  • 【愚公系列】《鸿蒙原生应用开发从零基础到多实战》001-TypeScript概述‌
  • 无人机避障——Mid360+Fast-lio感知建图+Ego-planner运动规划(胎教级教程)
  • Linux命令行导出Emacs ORG文档为HTML
  • Java 版 DeepSeek API 调用的小白详细教程
  • 最新华为 HCIP-Datacom(H12-821)2025.2.20
  • 计算机专业知识【MySQL 表名和列名使用中文的探讨】
  • uniapp 网络请求封装(uni.request 与 uView-Plus)
  • 【每日八股】计算机网络篇(一):概述
  • 实验 Figma MCP + Cursor 联合工作流
  • 基于Spring Boot的协同过滤电影推荐系统设计与实现(LW+源码+讲解)
  • 玩转SpringCloud Stream
  • 通过AI辅助生成PPT (by quqi99)