设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间01 现在时间01 缓存数据 当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

查看: 1427|回复: 2

Golang中实现简单的Http Middleware

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:233
  • 打卡月天数:0
  • 打卡总奖励:3699
  • 最近打卡:2025-09-08 14:17:14
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
411
主题
369
精华
0
金钱
4896
积分
849
注册时间
2023-1-8
最后登录
2025-9-8

发表于 2024-3-26 13:35:09 | 显示全部楼层 |阅读模式
本文主要针对Golang的内置库 net/http 做了简单的扩展,通过添加中间件的形式实现了管道(Pipeline)模式,这样的好处是各模块之间是低耦合的,符合单一职责原则,可以很灵活的通过中间件的形式添加一些功能到管道中,一次请求和响应在管道中的执行过程如下
1.png

首先, 我定义了三个测试的中间件 Middleware1,2,3 如下
  1. func Middleware1(next http.Handler) http.Handler {

  2.         return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  3.                 fmt.Println("M1 in")
  4.                 next.ServeHTTP(w, r)
  5.                 fmt.Println("M1 out")
  6.         })

  7. }

  8. func Middleware2(next http.Handler) http.Handler {

  9.         return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  10.                 fmt.Println("M2 in")
  11.                 next.ServeHTTP(w, r)
  12.                 fmt.Println("M2 out")
  13.         })

  14. }

  15. func Middleware3(next http.Handler) http.Handler {

  16.         return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  17.                 fmt.Println("M3 in")
  18.                 next.ServeHTTP(w, r)
  19.                 fmt.Println("M3 out")
  20.         })

  21. }
复制代码
这里中间件的入参和出参的类型都是 http.Handler, 然后在 next.ServeHTTP() 的前后分别输出了 In 和 Out.
接下来,定义一个 Pipeline 的方法,里面使用嵌套的形式, 使用了上面定义的三个测试的中间件.
  1. func Pipeline(next http.Handler) http.Handler {

  2.         return Middleware1(Middleware2(Middleware3(next)))

  3. }
复制代码
然后还需要业务代码,这里我定义了 LoginHandler 和 RegisterHandler 两个方法
  1. func LoginHandler(w http.ResponseWriter, r *http.Request) {

  2.         fmt.Println("Login...")
  3.         w.Write([]byte("Login..."))

  4. }

  5. func RegisterHandler(w http.ResponseWriter, r *http.Request) {

  6.         fmt.Println("Register...")
  7.         w.Write([]byte("Register..."))

  8. }
复制代码
最后修改程序的 main 函数, 在 Login 接口上使用上面添加过中间件的 Pipeline
  1. func main() {

  2.         http.Handle("/Login", Pipeline(http.HandlerFunc(LoginHandler)))

  3.         http.Handle("/Register", http.HandlerFunc(RegisterHandler))

  4.         http.ListenAndServe(":8080", nil)

  5. }
复制代码
启动程序后,访问 http://localhost:8080/Login, 程序的输出如下,这和本文最上面的管道的流程图是一致的,然后访问 Register 接口, 控制台没有输出信息,当然也不会执行任何中间件。
2.png

现在已经实现了中间件的机制,但是,上面添加中间件是用嵌套的方法,这种方式不能说不太优雅,只能说非常的Low,接下来我们需要对管道进行优化
  1. type Chain struct {
  2.         middlewares []func(handler http.Handler) http.Handler
  3. }


  4. func Pipeline(next http.Handler) http.Handler {

  5.         //return Middleware1(Middleware2(Middleware3(next)))

  6.         return AddMiddlewares(Middleware1,Middleware2,Middleware3).Then(next)

  7. }


  8. func AddMiddlewares(m ...func(handlerFunc http.Handler) http.Handler) Chain {

  9.         c := Chain{}

  10.         c.middlewares = append(c.middlewares,m...)

  11.         return c

  12. }


  13. func (c Chain) Then(next http.Handler) http.Handler {

  14.         for i := range c.middlewares {

  15.                 prev := c.middlewares[len(c.middlewares)-1-i]

  16.                 next = prev(next)
  17.         }

  18.         return next
  19. }
复制代码
首先定义了一个Chain 的struct,用来接收添加到管道中的中间件,在 AddMiddlewares() 函数中,接收了多个Handle, 然后组装到 Chain 对象并返回, 接下来调用 Then() 函数, 把管道中的中间件和业务的Handler 关联起来。在中间件的使用方式上, 这两种方法都是一样的,只需要调用 Pipeline() 方法就行了。
本文在go web中简单的实现了中间件的机制,这样带来的好处也是显而易见的,当然社区也有一些成熟的 middleware 组件,包括 Gin 一些Web框架中也包含了 middleware 相关的功能, 希望对您有用.
到此这篇关于Golang中实现简单的Http Middleware的文章就介绍到这了,更多相关Golang实现Http Middleware内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
20
积分
20
注册时间
2022-12-24
最后登录
2022-12-24

发表于 2024-4-4 02:47:00 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
15
积分
10
注册时间
2022-12-26
最后登录
2022-12-26

发表于 2025-12-11 18:28:32 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表