[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")

posted on 2022-07-20 10:42  进击的davis  阅读(3204)  评论(0编辑  收藏  举报

导航