[go-每日一库] golang实现gin的获取响应体内容,请求与响应体的改写与获取
参考:
由于在gin中不能直接获取响应体的信息,但可以通过Writer获取。
下面介绍下具体获取gin的响应的步骤。
1.定义新的ResponseWriter
代码:
type ResponseWriterWrapper struct {
gin.ResponseWriter
Body *bytes.Buffer // 缓存
}
func (w ResponseWriterWrapper) Write(b []byte) (int, error) {
w.Body.Write(b)
return w.ResponseWriter.Write(b)
}
func (w ResponseWriterWrapper) WriteString(s string) (int, error) {
w.Body.WriteString(s)
return w.ResponseWriter.WriteString(s)
}
2.在中间件中的使用
代码:
// middleware app debug log, 作用是记录请求响应的信息
func AppDebugLog() gin.HandlerFunc {
return func(ctx *gin.Context) {
// record request info
reqBody, _ := ioutil.ReadAll(ctx.Request.Body)
log.Logger.Info("requestInfo",
log.String("method", ctx.Request.Method),
log.Any("body", string(reqBody)),
log.String("clientIP", ctx.Request.RemoteAddr),
log.String("url", ctx.Request.RequestURI))
// record response info
blw := &ResponseWriterWrapper{Body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer}
ctx.Writer = blw
ctx.Next()
log.Logger.Info("responseInfo",
log.String("body", blw.Body.String()),
log.Int("statusCode", ctx.Writer.Status()))
}
}
3.注册中间件
server.Use(AppDebugLog())
最后再来看看在gin中如何获取请求体,响应体,以及如有需求改动body,我们又该如何操作。
4.请求体的获取与更改
获取及更改请求体
gin的请求体通过ctx.Request.Body获取,通过ioutil库读取响应body, 反序列化后即可操作,如果是改造请求体,则需要重新写回Request.Body中,所以再进行一次反序列化,显然频繁序列化操作影响内存和性能。
// 获取请求体
reqBody, _ := ioutil.ReadAll(ctx.Request.Body) // reqBody -> []byte
var m map[string]interface{}
_ = json.Unmarshal(reqBody, &m) // 反序列化
// e.g 加个字段
m["field1"] = "value1"
// 写回请求中
newBody, _ := json.Marshal(m)
ctx.Request.Body = ioutil.NopCloser(bytes.NewReader(newBody))
如果字段量少,也可以通过设置首部实现字段增加:
ctx.Request.Header.Set("field2", "value2")