新闻中心

如何在Golang中实现责任链过滤器_Golang 责任链模式过滤器实践

2025-11-21
浏览次数:
返回列表
责任链模式通过将请求沿处理器链传递实现解耦,Go 中可用函数类型定义过滤器,构建链式调用的中间件系统,适用于认证、校验、日志等场景。

如何在golang中实现责任链过滤器_golang 责任链模式过滤器实践

在 Go 语言中,责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理者链传递,每个处理者都有机会处理请求或将其传递给下一个处理者。这种模式非常适合实现过滤器系统,比如中间件、请求校验、日志记录等场景。

责任链模式的核心思想

责任链的核心是解耦请求发送者和接收者。多个处理器按顺序组成一条链,请求从链的一端进入,依次经过各个处理器,直到某个处理器处理完毕或链结束。

在 Web 框架或 API 中间件中,这种模式非常常见:身份验证 → 参数校验 → 日志记录 → 业务逻辑,每一个环节都可以是一个独立的过滤器。

定义处理器接口与结构体

在 Go 中,我们可以用函数类型或接口来定义处理器。这里使用函数类型更简洁直观:

定义 Handler 类型:

我们把每个过滤器定义为一个函数,接收一个 http.ResponseWriter*http.Request,并返回是否继续执行后续过滤器。

也可以封装成更通用的上下文对象,但为了简单起见,先基于标准库实现。

实现 Filter 接口:

创建一个 Filter 类型,表示单个过滤器:

type Filter func(http.ResponseWriter, *http.Request) bool

返回值 bool 表示是否继续向后传递请求。如果返回 false,则中断链式调用。

构建过滤器链

我们需要一个结构来管理多个过滤器,并按顺序执行它们。

小云雀 小云雀

剪映出品的AI视频和图片创作助手

小云雀 1949 查看详情 小云雀

定义一个 FilterChain 结构:

type FilterChain struct {
    filters []Filter
}
</p>

func NewFilterChain() *FilterChain {
    return &FilterChain{filters: make([]Filter, 0)}
}
</p>

func (fc *FilterChain) AddFilter(f Filter) {
    fc.filters = append(fc.filters, f)
}
</p>

func (fc *FilterChain) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    for _, filter := range fc.filters {
        if !filter(w, r) {
            return // 中断链
        }
    }
    // 所有过滤器通过后,执行最终逻辑
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Request processed successfully\n"))
}

编写具体过滤器示例

现在我们添加几个典型的过滤器来演示功能:

// 身份验证过滤器
func AuthFilter() Filter {
    return func(w http.ResponseWriter, r *http.Request) bool {
        token := r.Header.Get("Authorization")
        if token == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return false
        }
        return true
    }
}
</p>

// 日志记录过滤器
func LoggingFilter() Filter {
    return func(w http.ResponseWriter, r *http.Request) bool {
        log.Printf("Request: %s %s from %s", r.Method, r.URL.Path, r.RemoteAddr)
        return true
    }
}
</p>

// 参数校验过滤器
func ValidationFilter() Filter {
    return func(w http.ResponseWriter, r *http.Request) bool {
        if r.ContentLength > 1024*1024 {
            http.Error(w, "Payload too large", http.StatusRequestEntityTooLarge)
            return false
        }
        return true
    }
}

集成到 HTTP 服务中

将过滤器链注册为 HTTP 处理程序:

func main() {
    chain := NewFilterChain()
    chain.AddFilter(LoggingFilter())
    chain.AddFilter(AuthFilter())
    chain.AddFilter(ValidationFilter())

    http.Handle("/api/", chain)
    log.Println("Server starting on :8080")
    http.ListenAndServe(":8080", nil)
}

当请求到达 /api/xxx 时,会依次经过日志、认证、校验三个过滤器,全部通过才返回成功响应。

灵活扩展与实际应用建议

这种模式可以轻松扩展:

  • 支持动态添加/删除过滤器
  • 可为不同路由配置不同的链
  • 结合 context 实现跨过滤器的数据传递
  • 可用于 Gin、Echo 等框架的中间件开发

例如,在 Gin 中,你可以将每个 Filter 转换为 gin.HandlerFunc,实现类似的链式调用逻辑。

基本上就这些。Go 的函数式编程特性让责任链模式实现变得简洁高效,配合接口和组合机制,能构建出清晰、可维护的过滤器系统。

以上就是如何在Golang中实现责任链过滤器_Golang 责任链模式过滤器实践的详细内容,更多请关注其它相关文章!


# 复用  # 清镇seo关键词优化  # 怎么在百度查询关键词排名b2b  # 闲鱼约会关键词排名  # 温州seo营销推广  # 冬季营销推广文案怎么写  # 宜兰网站建设  # 甘泉抖音关键词排名  # 苏州抖音关键词排名团队  # 网站seo优化代理  # 互联网推广营销基础知识  # 都有  # 几个  # 是一个  # golang  # 身份验证  # 如何实现  # 如何使用  # 多个  # 如何在  # 链式  # 标准库  # 路由  # ai  # app  # 处理器  # go  # 责任链模式 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!  小米汽车11月交付量突破40000台!雷军:将继续努力  J*a实现学校排课程序_面向对象结构化项目示例  C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入  Android Studio计算器C键逻辑错误排查与修复:条件判断优化指南  解决Rails应用中内容错位与Turbo警告:meta标签误用导致富文本渲染异常  漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口  qq游戏免费畅玩入口_qq游戏电脑版快速启动  为什么简单的XML文件也会解析失败? 检查隐藏的非打印字符(如BOM)的方法  Golang如何优化内存分配与垃圾回收_Golang内存管理与GC优化实践  J*a TimerTask中HashMap意外清空的深层原因与解决方案  b站怎么删除评论_b站评论管理与删除操作  c++项目目录结构应该如何组织_c++工程化项目结构规范  如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率  CSS布局:解决全屏元素100%尺寸与外边距导致的页面溢出问题  内存疯狂猛猛涨价:主板销量直接腰斩!  QQ邮箱官方网页版登录 QQ邮箱个人邮箱快速访问  C++的std::mdspan是什么_C++23中用于操作多维数组的非拥有视图  使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战  C++编译期如何执行复杂计算_C++模板元编程(TMP)技巧与应用  微信商城在哪里打开【步骤】  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解  Win11网速慢怎么解决 Win11网络设置优化解除限速  QQ邮箱正确登录入口_QQ邮箱官方网站使用地址  抖音网页版企业服务中心登录入口_抖音网页版企业登录平台  12306选座系统怎么选连座_12306选座多人连坐操作方法  狙击外星人小游戏开始_狙击外星人小游戏立即开始  12306选座怎么选到临时改签座_12306改签选座策略与步骤  免费抖音短视频入口_抖音网页版短视频免费通道  快速CSGO开箱网站指南 CSGO开箱平台推荐  word中如何让数字纵向排列_Word数字纵向排列方法  React列表渲染与独立状态管理:避免全局状态影响局部更新  b站怎么取消点赞_b站点赞取消操作方法  QQ邮箱登录平台入口 QQ邮箱网页版邮箱官方入口  Go Martini框架:动态服务解码后的图片内容  夸克浏览器图书入口 夸克手机浏览器阅读入口  在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南  文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】  期待已久:小米17 Ultra、小米首款NAS本月登场  谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航  Python大型XML文件高效流式解析教程  Python模块化编程:有效管理依赖与避免循环引用  Win10如何恢复误删的快捷方式_Win10重建常用软件快捷方式  支付宝如何管理隐私设置_支付宝隐私保护的配置技巧  C++如何操作注册表_Windows平台下C++读写注册表的API函数详解  mcjs网页版流畅运行 mcjs低配电脑畅玩入口  Go语言中对Map值调用带指针接收者方法:原理与最佳实践  品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程  解决Python单元测试中Mock异常方法调用计数为零的问题 

搜索