package middleware import ( "bytes" "io" "strings" "code.yun.ink/pkg/ginx" "github.com/gin-gonic/gin" ) // 获取请求参数 func Params() gin.HandlerFunc { return func(ctx *gin.Context) { buf := &bytes.Buffer{} tea := io.TeeReader(ctx.Request.Body, buf) body, err := io.ReadAll(tea) if err != nil { ginx.Op.Logger.Errorf(ctx, "read body err=%+v", err) } ctx.Request.Body = io.NopCloser(buf) // 下面是响应参数缓存 blw := &bodyParamsWriter{ body: bytes.NewBufferString(""), ResponseWriter: ctx.Writer, } ctx.Writer = blw // 请求参数 rd := reqData{ Method: ctx.Request.Method, Path: ctx.FullPath(), ClientIP: ctx.ClientIP(), Body: string(body), Header: ctx.Request.Header, } ginx.Op.Logger.Info(ctx, "request params", rd) ctx.Next() // 判断返回的值是否json contentType := ctx.Writer.Header().Get("Content-Type") if !strings.Contains(contentType, "application/json") { return } resp := blw.body.String() rsd := respData{ HttpCode: ctx.Writer.Status(), Response: resp, // Header: ctx.Writer.Header(), } ginx.Op.Logger.Info(ctx, "response params", rsd) } } type reqData struct { Method string `json:"method"` Path string `json:"path"` ClientIP string `json:"client_ip"` Body string `json:"body"` Header map[string][]string `json:"header"` } type respData struct { HttpCode int `json:"http_code"` Response string `json:"response"` // Header map[string][]string `json:"header"` } type bodyParamsWriter struct { gin.ResponseWriter body *bytes.Buffer } // 真正输出的时候,它会调用这个输出方法 func (w bodyParamsWriter) Write(b []byte) (int, error) { // b = []byte(`{"code":0}`) w.body.Write(b) return w.ResponseWriter.Write(b) }