Golang Gin框架:如何移除请求Body中的空格与换行符
在Gin中间件中压缩JSON请求体日志(去除空格与换行)
因为直接通过字符串替换去除所有空格和换行可能会破坏JSON字符串内部的有效空格(比如示例中的"a "),所以推荐使用JSON标准库的工具来处理,既保证语法正确性,又能得到紧凑格式。
方法一:使用json.Compact(高效推荐)
json.Compact会直接压缩JSON字节流,仅移除JSON语法层面的空白字符(包括空格、换行、制表符等),保留字符串内部的空格,且性能比先解码再编码更好。
import ( "bytes" "encoding/json" "io" "log" "github.com/gin-gonic/gin" ) func RequestLogMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 读取并备份请求Body(Body只能读取一次,需重置) var rawBody []byte if c.Request.Body != nil { var err error rawBody, err = io.ReadAll(c.Request.Body) if err == nil { // 将读取后的Body重新放回,确保后续处理器能正常读取 c.Request.Body = io.NopCloser(bytes.NewBuffer(rawBody)) } } // 处理JSON压缩 var compactBody []byte if len(rawBody) > 0 { compactBody = make([]byte, 0, len(rawBody)) // 尝试压缩JSON,失败则使用原内容(兼容非JSON请求) if err := json.Compact(&compactBody, rawBody); err != nil { compactBody = rawBody } } // 打印日志(替换为你的实际日志调用) log.Printf("request_in||traceid=xx||spanid=xxx||path=%s||body=%s", c.Request.URL.Path, string(compactBody)) c.Next() } }
方法二:先解码再重新编码(通用兼容)
如果需要对JSON做额外处理(比如过滤敏感字段),可以先将JSON解码为interface{},再用json.Marshal编码(默认生成紧凑格式):
import ( "bytes" "encoding/json" "io" "log" "github.com/gin-gonic/gin" ) func RequestLogMiddleware() gin.HandlerFunc { return func(c *gin.Context) { var rawBody []byte if c.Request.Body != nil { var err error rawBody, err = io.ReadAll(c.Request.Body) if err == nil { c.Request.Body = io.NopCloser(bytes.NewBuffer(rawBody)) } } var compactBody []byte if len(rawBody) > 0 { var temp interface{} // 尝试解码JSON,失败则用原内容 if err := json.Unmarshal(rawBody, &temp); err == nil { compactBody, _ = json.Marshal(temp) } else { compactBody = rawBody } } log.Printf("request_in||traceid=xx||spanid=xxx||path=%s||body=%s", c.Request.URL.Path, string(compactBody)) c.Next() } }
关键注意点
- 重置请求Body:读取Body后必须用
io.NopCloser重新包装并赋值回c.Request.Body,否则后续的Gin控制器无法读取请求参数。 - 兼容非JSON请求:加入错误判断,当请求Body不是JSON格式时,直接使用原始内容,避免日志打印报错。
- 保留有效空格:两种方法都不会修改JSON字符串内部的空格(比如示例中的
"a "),仅去除语法层面的空白,保证日志数据的准确性。
内容的提问来源于stack exchange,提问作者kuat
相关产品推荐
相关产品推荐

