我正在尝试为多个处理程序设置http标头 . 我的第一个想法是创建一个自定义写入函数,在写入响应之前设置 Headers ,就像底部的代码示例一样 .
但是,当我将指针传递给http.ResponseWriter并尝试从我的函数访问它时,它告诉我“type * http.ResponseWriter没有Header方法” .
为多个处理程序设置标头的最佳方法是什么,以及为什么指针不按我想要的方式工作?
func HelloServer(w http.ResponseWriter, req *http.Request) {
type Message struct {
Name string
Body string
Time int64
}
m := Message{"Alice", "Hello", 1294706395881547000}
b, _ := json.Marshal(m)
WriteJSON(&w, b)
}
func WriteJSON(wr *http.ResponseWriter, rawJSON []byte) {
*wr.Header().Set("Content-Type", "application/json")
io.WriteString(*wr, string(rawJSON))
}
func main() {
http.HandleFunc("/json", HelloServer)
err := http.ListenAndServe(":9000", nil)
if err != nil {
log.Fatal("ListenAndServer: ", err)
}
}
4 回答
我不确定多处理程序的事情,但我知道为什么你写的代码失败了 . 关键是该行:
由于运算符优先级,正被解释为:
由于
wr
的类型为*http.ResponseWriter
,它是指向和接口的指针,而不是接口本身,因此不起作用 . 我假设你知道,这就是为什么你做了*wr
. 我假设你对编译器意味着什么:如果我没有弄错的话,那应该编译并且行为正常 .
您不需要使用
*wr
,因为它已经引用了指针 .wr.Header().Set("Content-Type", "application/json")
应该足够了 .如果要为每个请求设置"global"标头,可以创建一个满足
http.HandleFunc
(go.auth has a good example)的函数,然后像这样包装处理程序:http.HandleFunc("/hello", Defaults(helloHandler))
另请查看
net/http
文档,which has further examples .我用一个调用我的AddSafeHeader函数的错误处理程序包装我的处理程序 .
我基于http://golang.org/doc/articles/error_handling.html但它不使用ServeHTTP所以它适用于appstats:
这里:
http.ResponseWriter是一个界面 .
您可能不应该使用指向接口的指针 . 在net / http / server.go中,未导出的
response
结构是服务器调用处理程序时实现ResponseWriter
的实际类型,重要的是when the server actually calls the handler's ServeHTTP,它传递 *response . 它已经是一个指针,但你没有看到,因为ResonseWriter
是一个接口 . (响应指针由here创建here . (链接可能是未来的错误行,但您应该能够找到它们) .这就是实现
Handler
所需的ServeHTTP
函数的原因:即不是指向
ResponseWriter
的指针,因为此声明已经允许指向实现ResponseWriter
接口的结构的指针 .