我正在用 Go 编写一个 Web 应用程序,虽然各种 mux 库提供了一种设置自定义 404 错误处理程序的方法,但没有其他 4xx 和 5xx 错误代码。
一个建议是重写 ResponseWriter 接口中的 WriteHeader 方法并检查状态代码,但我对实际如何编写它感到困惑(在输出之前重写 ResponseWriter 方法)。一个可能的例子可以从negroni 包中找到。
这是为 4xx 和 5xx 错误提供自定义模板的正确方法吗?谁能提供一个如何实施的例子?
非常感谢 David 和 elithrar 的回复和代码。David 编码的结构Interceptor可以在服务器复用器的包装器中使用,如 elithrar 在注释中所示。对于那些想要进一步解释其工作原理和原因的人,astaxie 书中的这一部分提供了一些有关 net/http 包工作原理的非常好的信息,以及查看net/http 包中的server.go 源代码。
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)