## 内容渲染 Web处理程序可以返回各种内容类型,例如,JSON,纯文本,图像等。 通常在与API通信时,可以指定并接收内容类型,以阐明将传入数据的格式以及要接收的数据。 本节将通过第三方库对数据格式进行切换。 ### 实践 1. 获取第三方库: ``` go get github.com/unrolled/render ``` 2. 建立 negotiate.go: ``` package negotiate import ( "net/http" "github.com/unrolled/render" ) // Negotiator 封装render并对ContentType进行一些切换 type Negotiator struct { ContentType string *render.Render } // GetNegotiator 接收http请求 并从Content-Type标头中找出ContentType func GetNegotiator(r *http.Request) *Negotiator { contentType := r.Header.Get("Content-Type") return &Negotiator{ ContentType: contentType, Render: render.New(), } } ``` 3. 建立 respond.go: ``` package negotiate import "io" import "github.com/unrolled/render" // Respond 根据 Content Type 判断应该返回什么样类型的数据 func (n *Negotiator) Respond(w io.Writer, status int, v interface{}) { switch n.ContentType { case render.ContentJSON: n.Render.JSON(w, status, v) case render.ContentXML: n.Render.XML(w, status, v) default: n.Render.JSON(w, status, v) } } ``` 4. 建立 handler.go: ``` package negotiate import ( "encoding/xml" "net/http" ) // Payload 甚至数据模板 type Payload struct { XMLName xml.Name `xml:"payload" json:"-"` Status string `xml:"status" json:"status"` } // Handler 调用GetNegotiator处理返回格式 func Handler(w http.ResponseWriter, r *http.Request) { n := GetNegotiator(r) n.Respond(w, http.StatusOK, &Payload{Status: "Successful!"}) } ``` 5. 建立 main.go: ``` package main import ( "fmt" "net/http" "github.com/agtorre/go-cookbook/chapter7/negotiate" ) func main() { http.HandleFunc("/", negotiate.Handler) fmt.Println("Listening on port :3333") err := http.ListenAndServe(":3333", nil) panic(err) } ``` 6. 运行: ``` $ go run main.go Listening on port :3333 $curl "http://localhost:3333 -H "Content-Type: text/xml" <payload><status>Successful!</status></payload> $curl "http://localhost:3333 -H "Content-Type: application/json" {"status":"Successful!"} ``` ### 说明 github.com/unrolled/render 包可以帮助你处理各种类型的请求头。请求头通常包含多个值,您的代码必须考虑到这一点。 * * * * 学识浅薄,错误在所难免。欢迎在群中就本书提出修改意见,以飨后来者,长风拜谢。 Golang中国(211938256) beego实战(258969317) Go实践(386056972)