背景:给予gin 框架的服务,想写一个中间件,保存操作信息到数据库。 字段包括请求的数据,也就是需要获取 请求参数中的body,、
像这样,
appGp.POST("delAddAdministrator", middlewares.LogMiddleWare, api.DelAddAdministrator)
遇到的问题:
中间件 获取不到 body的内容,一直为空,
错误信息
"error": "Error 1136: Column count doesn't match value count at row 1"} 2022-04-29T11:25:15.891+0800 INFO logger/logger.go:91 /v1/appLog {"status": 200, "method": "POST", "path": "/v1/appLog", "query": "", "ip": "127.0.0.1", "user-agent": "PostmanRuntime/7.29.0", "errors": "", "cost": " 2.416ms"}
经过网络查找,可能是 go gin body的内容只能读取一次,后面在读取都是空的问题。
解决方案:
参考文档 https://blog.csdn.net/impressionw/article/details/84194783
最终的中间件:
func LogMiddleWare(ctx *gin.Context) { staffName := ctx.Request.Header.Get("staff_name") stafEmail := ctx.Request.Header.Get("staff_email") staffId := ctx.Request.Header.Get("staff_id") if staffName == "" || stafEmail == "" || staffId == "" { base.ResponseError(ctx, base.AuthFail) ctx.Abort() return } // 1、获取请求body data, err := ctx.GetRawData() if err != nil { fmt.Println(err.Error()) } fmt.Printf("data: %v\n", string(data)) logdata := &dto.AppLog{} logdata.Operator = staffName logdata.RequestData = string(data) logdata.CreatedTime = time.Now() logdata.Ip = ctx.ClientIP() logdata.Operation = ctx.Request.URL.Path err = dao.AppLogDao(logdata) //2、 gin body 只能获取一次,上面获取之后,一定要 再次给 context 赋值 不然 后面接口就获取不到了。 ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data)) // 关键点 ctx.Next() }