重写 ResponseWriter 接口以捕获 HTTP 错误

Con*_*r H 4 go

我正在用 Go 编写一个 Web 应用程序,虽然各种 mux 库提供了一种设置自定义 404 错误处理程序的方法,但没有其他 4xx 和 5xx 错误代码。

一个建议是重写 ResponseWriter 接口中的 WriteHeader 方法并检查状态代码,但我对实际如何编写它感到困惑(在输出之前重写 ResponseWriter 方法)。一个可能的例子可以从negroni 包中找到。

这是为 4xx 和 5xx 错误提供自定义模板的正确方法吗?谁能提供一个如何实施的例子?

更新

非常感谢 David 和 elithrar 的回复和代码。David 编码的结构Interceptor可以在服务器复用器的包装器中使用,如 elithrar 在注释中所示。对于那些想要进一步解释其工作原理和原因的人,astaxie 书中的这一部分提供了一些有关 net/http 包工作原理的非常好的信息,以及查看net/http 包中的server.go 源代码。

Dav*_*rth 5

mux 库只有一种设置未找到处理程序的方法,作为一种方法来拦截 mux 无法将 URL 解析为其已知映射的请求。

例如,您这样做:

mux.Handle("/foo",fooFunc)
mux.Handle("/bar",barFunc)
Run Code Online (Sandbox Code Playgroud)

/baz多路复用器访问的客户端没有映射。

他们实际上并没有拦截发送给客户端的 404 错误,只是在遇到此问题时调用未找到的处理程序。

另外,如果您的 /foo 处理程序发送 404 响应,则不会调用 not find 。

如果您想要从映射的 URL 获取各种返回响应的自定义页面,只需让各种处理程序编写正确的响应即可。

如果您不控制该逻辑(即:框架正在编写某些内容并且无法覆盖),那么您可能希望拦截所有请求并使用响应代码检测逻辑覆盖 http.ResposeWriter 。

这是一个示例拦截器,基本上可以完成您想要的操作。播放

package main

import (
    "fmt"
    "log"
)
import "net/http"

type Interceptor struct {
    origWriter http.ResponseWriter
    overridden bool
}

func (i *Interceptor) WriteHeader(rc int) {
    switch rc {
    case 500:
        http.Error(i.origWriter, "Custom 500 message / content", 500)
    case 404:
        http.Error(i.origWriter, "Custom 404 message", 404)
    case 403:
        i.origWriter.WriteHeader(403)
        fmt.Fprintln(i.origWriter, "Custom 403 message")
    default:
        i.origWriter.WriteHeader(rc)
        return
    }
    // if the default case didn't execute (and return) we must have overridden the output
    i.overridden = true
    log.Println(i.overridden)
}

func (i *Interceptor) Write(b []byte) (int, error) {
    if !i.overridden {
        return i.origWriter.Write(b)
    }

    // Return nothing if we've overriden the response.
    return 0, nil
}

func (i *Interceptor) Header() http.Header {
    return i.origWriter.Header()
}
Run Code Online (Sandbox Code Playgroud)