Day05:Gin框架快速入门05 中间件和路由 | 青训营

简介: Day05:Gin框架快速入门05 中间件和路由 | 青训营

导读

本套笔记是为了学习过其他语言框架,想要快速掌握gin框架推行的一套笔记。 虽然为了青训营而制作的一套笔记,但其他想要学go的程序员也可以通过这个上手go世界,后续会带你快速上手gorm,学完这两个之后,简体版抖音基本上就可以独立完成了,后续还会进行大项目的讲解开发,制作不易,喜欢的就点个关注吧。

注意

代码详解大部分是注释的形式给出,请留意代码注释。

Gin框架介绍

导读:Gin是一个非常受欢迎的Golang Web框架,它旨在提供高性能、易用和轻量级的解决方案。

中间件

中间件(Middleware)是在应用程序处理请求和生成响应之间执行的一系列功能组件。它请求到达目标处理程序之前或响应回传给客户端之前,对请求和响应进行预处理或后处理。类似java的拦截器。

大白话:Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数,这个钩子函数就叫中间件。

在 Gin 框架中,gin.HandlerFunc 是一个具有特定签名的函数类型,它接受一个 *gin.Context 参数,并没有返回值。这个函数类型被用作中间件函数和路由处理函数的类型,Gin中的中间件必须是一个gin.HandlerFunc类型。

单独注册中间件

package main  
import (  
"fmt"  
"github.com/gin-gonic/gin"  
"net/http"  
)  
func get(c *gin.Context) {  
fmt.Println("get运行了")  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
}  
//定义一个中间件  
func m1(c *gin.Context) {  
fmt.Println("中间件运行了")  
}  
func main() {  
router := gin.Default()  
router.GET("/get", m1, get)  
router.Run(":8080")  
}

当我们运行之后,发送send,会执行m1,之后执行get。

image.png

postman接收到信息

image.png

多个中间件

router.GET,后面可以跟很多HandlerFunc方法,这些方法其实都可以叫中间件

package main  
import (  
"fmt"  
"github.com/gin-gonic/gin"  
"net/http"  
)  
func get(c *gin.Context) {  
fmt.Println("get运行了")  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
}  
// 定义一个中间件  
func m1(c *gin.Context) {  
fmt.Println("m1运行了")  
}  
func m2(c *gin.Context) {  
fmt.Println("m2运行了")  
}  
func main() {  
router := gin.Default()  
router.GET("/get", m1, get,m2)  
router.Run(":8080")  
}

运行结果如下

image.png

先运行m1,之后运行get,最后运行m2,以此类推,也可以增加更多的中间件

中间件拦截响应

只需要修改m1

// 定义一个中间件  
func m1(c *gin.Context) {  
fmt.Println("m1运行了")
//用于终止请求的处理流程并立即返回响应
c.Abort()  
}

运行结果

image.png

可以看到只有m1运行了

中间件放行

使用c.next()进行放行,会直接运行下一个方法,下一个方法运行结束之后运行c.next()之后的方法

修改代码

func get(c *gin.Context) {  
fmt.Println("get运行了")  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
c.Next()  
fmt.Println("get再次运行")  
}  
// 定义一个中间件  
func m1(c *gin.Context) {  
fmt.Println("m1运行了")  
c.Next()  
fmt.Println("m1再次运行")  
}  
func m2(c *gin.Context) {  
fmt.Println("m2运行了")  
c.Next()  
fmt.Println("m2再次运行")  
}

运行结果如图

image.png

注意:如果其中一个中间件响应了c.Abort(),后续中间件将不再执行,直接按照顺序走完所有的响应中间件

全局注册中间件

在 Gin 框架中,Use 方法用于将中间件函数注册到全局中间件链中。全局中间件会在每个请求处理之前都被执行,无论请求的路径是什么。使用Use去注册全局中间件,Use接收的参数也是多个HandlerFunc

package main  
import (  
"fmt"  
"github.com/gin-gonic/gin"  
"net/http"  
)  
func get(c *gin.Context) {  
fmt.Println("get运行了")  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
c.Next()  
fmt.Println("get再次运行")  
}  
func m10(c *gin.Context) {  
fmt.Println("m10运行了")  
}  
func main() {  
router := gin.Default()  
router.Use(m10)  
router.GET("/get", get)  
router.POST("/post", get)  
router.Run(":8080")  
}

我们使用getpost分别发送请求,m10都会先运行。

中间件传递数据

我们使用c.Get()c.Set()方法来传递数据

c.Set() 是 Gin 框架中的方法,用于在请求处理过程中设置键值对数据。

c.Get() 是 Gin 框架中的方法,用于获取在请求处理过程中设置的键值对数据。

package main  
import (  
"fmt"  
"github.com/gin-gonic/gin"  
"net/http"  
)  
func get(c *gin.Context) {  
name, _ := c.Get("name")//获得数据  
fmt.Println(name)  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
c.Next()  
}  
func m10(c *gin.Context) {  
fmt.Println("m10运行了")  
c.Set("name", "xiaoming") //定义一个数据 
}  
func main() {  
router := gin.Default()  
router.Use(m10)  
router.GET("/get", get)  
router.Run(":8080")  
}

运行结果

image.png

可以看到成功拿到了数据name

Set()第二个参数是any类型,所有我们可以用它传任意类型,在接收的时候做好断言即可 例如一个结构体

package main  
import (  
"fmt"  
"github.com/gin-gonic/gin"  
"net/http"  
)  
type User struct {  
Name string  
Age int  
} //定义user结构体 
func get(c *gin.Context) {  
name, _ := c.Get("user") //获得结构退 
fmt.Println(name)//打印结构体  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})//响应信息 
c.Next()  
}  
func m10(c *gin.Context) {  
fmt.Println("m10运行了")  
c.Set("user", User{  
Name: "xiaoming",  
Age: 18,  
}) 构造结构体user 
}  
func main() {  
router := gin.Default()  
router.Use(m10)  
router.GET("/get", get)  
router.Run(":8080")  
}

运行结果

image.png

路由

路由分组

将一系列的路由放到一个组下,统一管理

package main  
import (  
"github.com/gin-gonic/gin"  
"net/http"  
)  
func get(c *gin.Context) {  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
}  
func main() {  
router := gin.Default()  
r := router.Group("/group") //分组 
r.GET("/get", get)  
r.POST("/post", get)  
router.Run(":8080")  
}

这样在postman里面我们如果要发送请求,只需要这样

image.png

image.png

两个响应的结果都是一样的

image.png

路由分组注册中间件

就是在分组后面加上Use就可以了

package main  
import (  
"fmt"  
"github.com/gin-gonic/gin"  
"net/http"  
)  
func middle(c *gin.Context) {  
fmt.Println("middle ...in")  
}  
func get(c *gin.Context) {  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
}  
func main() {  
router := gin.Default()  
r := router.Group("/group").Use(middle) //分组并且使用全局中间件 
r.GET("/get", get)  
r.POST("/post", get)  
router.Run(":8080")  
}

分别发送请求之后

image.png

权限验证

以前后端最流行的jwt为例,如果用户登录了,前端发来的每一次请求都会在请求头上携带上token

后台拿到这个token进行校验,验证是否过期,是否非法

如果通过就说明这个用户是登录过的

不通过就说明用户没有登录

package main  
import (  
"github.com/gin-gonic/gin"  
"net/http"  
)  
 //验证jwt令牌是否正确的方法
 //每次都要验证
func JwtTokenMiddleware(c *gin.Context) {  
// 获取请求头的token  
token := c.GetHeader("token")  
// 调用jwt的验证函数  
if token == "1234" {  
// 验证通过  
c.Next()  
return  
}  
// 验证不通过  
c.JSON(200, gin.H{"msg": "权限验证失败"})  
c.Abort()  
}  
func get(c *gin.Context) {  
c.JSON(http.StatusOK, gin.H{  
"msg": "ok",  
})  
}  
func main() {  
router := gin.Default()  
r := router.Group("/group").Use(JwtTokenMiddleware)  
r.GET("/get", get)  
r.POST("/post", get)  
router.Run(":8080")  
}

我们使用postman发送请求

1: 如果token != 1234

image.png

2: 如果token = 1234

image.png


相关文章
|
1月前
|
JSON 中间件 Java
【GoGin】(3)Gin的数据渲染和中间件的使用:数据渲染、返回JSON、浅.JSON()源码、中间件、Next()方法
我们在正常注册中间件时,会打断原有的运行流程,但是你可以在中间件函数内部添加Next()方法,这样可以让原有的运行流程继续执行,当原有的运行流程结束后再回来执行中间件内部的内容。​ c.Writer.WriteHeaderNow()还会写入文本流中。可以看到使用next后,正常执行流程中并没有获得到中间件设置的值。接口还提供了一个可以修改ContentType的方法。判断了传入的状态码是否符合正确的状态码,并返回。在内部封装时,只是标注了不同的render类型。再看一下其他返回的类型;
154 3
|
5月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
数据采集 中间件 开发者
Scrapy爬虫框架-自定义中间件
Scrapy爬虫框架-自定义中间件
201 1
|
缓存 中间件 网络架构
Python Web开发实战:高效利用路由与中间件提升应用性能
在Python Web开发中,路由和中间件是构建高效、可扩展应用的核心组件。路由通过装饰器如`@app.route()`将HTTP请求映射到处理函数;中间件则在请求处理流程中插入自定义逻辑,如日志记录和验证。合理设计路由和中间件能显著提升应用性能和可维护性。本文以Flask为例,详细介绍如何优化路由、避免冲突、使用蓝图管理大型应用,并通过中间件实现缓存、请求验证及异常处理等功能,帮助你构建快速且健壮的Web应用。
121 1
|
缓存 监控 安全
中间件在Python Web框架中的角色与应用场景
【7月更文挑战第21天】中间件在Python Web开发中作为服务器与应用间的软件层,拦截、处理请求和响应,无需改动应用代码。它扩展框架功能,复用跨应用逻辑,加强安全,优化性能。如Django中间件处理请求/响应,Flask通过WSGI中间件实现类似功能,两者均在不触及核心代码前提下,灵活增强应用行为,是现代Web开发关键组件。
254 0
|
缓存 中间件 网络架构
Python Web开发实战:高效利用路由与中间件提升应用性能
【7月更文挑战第20天】在Python Web开发中,路由与中间件是构建高效应用的核心。路由通过装饰器如`@app.route()`在Flask中映射请求至处理函数;中间件(如`@app.before_request`, `@app.after_request`)则在请求流程中插入自定义逻辑。优化路由包括减少冲突、利用动态参数及蓝图;中间件可用于缓存响应、请求验证和异常处理,显著提升性能和可维护性。良好设计是关键,示例代码展示了如何在Flask中实现这些策略。
164 0
|
中间件 数据库 开发者
解析Python Web框架的四大支柱:模板、ORM、中间件与路由
【7月更文挑战第20天】Python Web框架如Django、Flask、FastAPI的核心包括模板(如Django的DTL和Flask的Jinja2)、ORM(Django的内置ORM与Flask的SQLAlchemy)、中间件(Django的全局中间件与Flask的装饰器实现)和路由(Django的urls.py配置与Flask的@app.route()装饰器)。这些组件提升了代码组织和数据库操作的便捷性,确保了Web应用的稳定性和可扩展性。
226 0
|
中间件 API 开发者
深入理解Python Web框架:中间件的工作原理与应用策略
【7月更文挑战第19天】Python Web中间件摘要:**中间件是扩展框架功能的关键组件,它拦截并处理请求与响应。在Flask中,通过`before_request`和`after_request`装饰器模拟中间件行为;Django则有官方中间件系统,需实现如`process_request`和`process_response`等方法。中间件用于日志、验证等场景,但应考虑性能、执行顺序、错误处理和代码可维护性。
259 0
|
消息中间件 存储 中间件
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
11937 1
|
消息中间件 编解码 Docker
Docker部署RabbitMQ消息中间件
【7月更文挑战第4天】Docker部署RabbitMQ消息中间件
486 3