我在Go中编写了一个Web应用程序,虽然各种mux库提供了一种设置自定义404错误处理程序的方法,但其他4xx和5xx错误代码却没有。
一个建议是覆盖ResponseWriter接口中的WriteHeader方法并检查状态代码,但我对如何实际编写它(在输出之前覆盖ResponseWriter方法)感到困惑。可以从negroni package找到一个可能的示例。
这是为4xx和5xx错误提供自定义模板的正确方法吗?任何人都可以提供一个如何实现这个的例子吗?
非常感谢David和elithrar的回复和代码。 David编码的Interceptor
结构可以在服务器mux的包装器中使用,正如elithrar在注释中所示。对于那些希望进一步解释为什么以及如何工作的人,this section from astaxie's book提供了一些关于net / http包的工作原理的非常好的信息,以及从net / http包中查看server.go source code。
答案 0 :(得分:3)
mux库只能设置未找到的处理程序,以便为您提供一种拦截请求的方法,其中多路复用器可以解析其已知映射的URL。
例如,你这样做:
mux.Handle("/foo",fooFunc)
mux.Handle("/bar",barFunc)
但客户端访问多路复用器没有映射的/baz
。
它们实际上并不拦截进入客户端的404,它们只是在遇到此问题时调用未找到的处理程序。
此外,如果您的/ foo处理程序发送404响应,则不会调用未找到的。
如果您想要从映射的URL中获取各种返回响应的自定义页面,只需让各种处理程序写出正确的响应即可。
如果你不控制那个逻辑(即:框架正在编写某些东西而无法覆盖),那么你可能想拦截所有请求并用响应代码检测逻辑覆盖http.ResposeWriter。 / p>
这是一个基本上做你想要的拦截器的示例。在Play
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()
}