我正在用Go编写Web应用程序的代码,尽管各种mux库提供了一种设置自定义404错误处理程序的方法,但其他4xx和5xx错误代码却一无所获。
一种建议是在ResponseWriter界面中重写WriteHeader方法并检查状态代码,但是我对如何实际写入感到困惑(在输出之前重写ResponseWriter方法)。从negroni包中可以找到一个可能的例子。
这是为4xx和5xx错误提供自定义模板的正确方法吗?谁能提供一个示例说明如何实现?
非常感谢David和elithrar的回复和代码。InterceptorDavid编码的结构可以在服务器多路复用器的包装器中使用,如elithrar在注释中所示。对于那些寻求进一步解释其原因和方式的人,astaxie的书中的这一节提供了有关net / http包工作原理的一些很好的信息,以及从net / http包中查看server.go源代码。
Interceptor
Mux库只有一种设置未找到的处理程序的方法,它为您提供了一种在Mux无法将URL解析为其已知映射的情况下拦截请求的方法。
例如,您这样做:
mux.Handle("/foo",fooFunc) mux.Handle("/bar",barFunc)
但是客户端访问/baz的多路复用器没有映射。
/baz
他们实际上并没有截取去往客户端的404,而只是在遇到此问题时调用未找到的处理程序。
此外,如果/ foo处理程序发送404响应,则不会调用未找到的响应。
如果您希望自定义页面用于来自映射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() }