type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data map[string]interface{} `json:"data"` }阅读上面这段代码,我们定义一个自定义结构体类型 Response,该结构体类型包含 3 个字段,分别是 Code,Msg,Data,并且分别定义了 json 标签。
func GetData(c *gin.Context) (data *Response) { value, exists := c.Get("data") if !exists { data = &Response{ Code: http.StatusOK, } data.Data = make(map[string]interface{}) c.Set("data", data) return } if data, exists = value.(*Response); !exists { data = &Response{Code: http.StatusInternalServerError} return } return }阅读上面这段代码,我们使用 Gin 框架的 gin.Context 的存储数据,通过 Set 和 Get 方法,设置和获取数据。
func ValidatorAndReturn(c *gin.Context, arg interface{}) (data *Response, err error) { data = GetData(c) err = c.ShouldBind(arg) if err != nil { return } return }阅读上面这段代码,我们定义一个函数,接收参数是 *gin.Context 类型的变量 c,和 interface{} 类型的变量 arg,返回结果是 *Response 类型的 data 和 error 类型的 err。函数体中,包含自定义函数 GetData 和 ShouldBind 方法。读者朋友们,可以根据自己的项目,优化验证请求参数的代码。
// ResponseReturn middleware func ResponseReturn() gin.HandlerFunc { return func(c *gin.Context) { data := GetData(c) c.Render(http.StatusOK, ReturnJson{Data: data}) } }阅读上面这段代码,我们定义一个中间件函数 ResponseReturn,使用 gin.Context 的 Render 方法,返回响应数据。
type Render interface { Render(http.ResponseWriter) error WriteContentType(w http.ResponseWriter) }阅读 Gin 框架源码,我们可以发现 render.Render 是一个接口类型,包含两个方法,分别是 Render 和 WriteContentType。所以,我们定义了一个结构体 ReturnJson,并实现 render.Render 的两个方法,示例代码:
var contentType = []string{"application/json; charset=utf-8"} // 堆代码 duidaima.com type ReturnJson struct { Data interface{} } func responseContentType(w http.ResponseWriter, contentType []string) { header := w.Header() if val := header["Content-Type"]; len(val) == 0 { header["Content-Type"] = contentType } } func ResponseJson(w http.ResponseWriter, data interface{}) (err error) { responseContentType(w, contentType) bf := bytes.NewBuffer([]byte{}) jsonEncoder := json.NewEncoder(bf) jsonEncoder.SetEscapeHTML(false) err = jsonEncoder.Encode(data) if err != nil { return } _, err = w.Write(bf.Bytes()) if err != nil { return } return } func (r ReturnJson) Render(w http.ResponseWriter) (err error) { err = ResponseJson(w, r.Data) if err != nil { return } return } func (r ReturnJson) WriteContentType(w http.ResponseWriter) { responseContentType(w, contentType) }阅读上面这段代码,我们定义结构体类型的自定义类型 ReturnJson,并创建两个方法 Render 和 WriteContentType,从而实现接口类型 render.Render,作为 c.Render 的参数。
我们通过三个步骤完成,
第一,创建返回响应数据的函数;
第二,创建验证请求参数和返回响应数据的整合函数;
第三,创建返回响应数据的中间件函数。