Go语言http handler条件链式调用问题:SpecificCheck的HandlerFunc未触发如何解决
问题根因
你现有代码的核心问题有两个:
- 条件成立的分支中,仅调用了
SpecificCheck(arg),该方法仅返回中间件构造函数,你没有将后续的handler链传入构造出实际可执行的http.Handler,也没有调用其ServeHTTP方法,所以对应逻辑完全不会触发 - 你没有对context取值的
ok结果做判断,若context中不存在对应key、或值的类型不匹配,check会直接取bool类型的零值false,可能不符合你的业务预期
正确实现方案
修改ConditionalCheck的逻辑,条件成立时将SpecificCheck返回的中间件套在原有handler链上执行即可,完整代码如下:
func ConditionalCheck(arg string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() check, ok := ctx.Value("specific").(bool) if ok && check { // 用SpecificCheck中间件包裹后续handler链,直接执行 SpecificCheck(arg)(next).ServeHTTP(w, r) return } // 条件不成立直接走后续handler next.ServeHTTP(w, r) }) } } func SpecificCheck(arg string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 你的SpecificCheck业务逻辑写在这里 // ... next.ServeHTTP(w, r) }) } } // alice初始化时要先给ConditionalCheck传入参数,得到符合要求的中间件实例 chain := alice.New(ConditionalCheck("你要传入的参数"), 其他中间件...)
额外注意事项
- 如果
SpecificCheck逻辑不需要继续走后续handler链,可以删除SpecificCheck内部的next.ServeHTTP调用,直接返回响应即可 - 建议用自定义类型作为context的key,避免和其他包的key产生冲突,示例如下:
type contextKey string const specificCheckKey contextKey = "specific" // 存值时使用:ctx = context.WithValue(ctx, specificCheckKey, true) // 取值时使用:check, ok := ctx.Value(specificCheckKey).(bool)
内容的提问来源于stack exchange,提问作者RaceBase
相关产品推荐
相关产品推荐

