From 2aa8e8691784b992992165be33517745d98c658e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 4 May 2025 14:36:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7body=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 4 +- go.sum | 6 +++ request/abstract/parse_body.go | 10 +--- request/parse_body/base.go | 46 ----------------- request/parse_body/execute.go | 72 +++++++++++++++++++++------ request/parse_body/form_url_encode.go | 44 ---------------- request/parse_body/json.go | 49 ------------------ request/parse_body/xml.go | 42 ---------------- request/parse_body/yml.go | 8 --- 9 files changed, 67 insertions(+), 214 deletions(-) delete mode 100644 request/parse_body/base.go delete mode 100644 request/parse_body/form_url_encode.go delete mode 100644 request/parse_body/json.go delete mode 100644 request/parse_body/xml.go delete mode 100644 request/parse_body/yml.go diff --git a/go.mod b/go.mod index b9d619c..c27be65 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06 git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 - git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58 + git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9 git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 github.com/gin-gonic/gin v1.10.0 github.com/go-playground/validator/v10 v10.26.0 @@ -34,7 +34,7 @@ require ( github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cloudwego/base64x v0.1.5 // indirect github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect - github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gabriel-vasile/mimetype v1.4.9 // indirect github.com/gin-contrib/pprof v1.5.2 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect diff --git a/go.sum b/go.sum index 31d6d44..22f36c7 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,10 @@ git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7G git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58 h1:fTkmucGaUoKocoX+ASM4AnwsAVJOtOOLUFSqA+uwVzg= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58/go.mod h1:Ig3GZC2hJDkQp7F8Tm53GvMWLh9bdbbauow/vxGO4YA= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250503114548-0c3d7b7e92eb h1:2kWDxCHTFfFTb4aPcM3wL/wYfsKHy3XdtEutl+a64lM= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250503114548-0c3d7b7e92eb/go.mod h1:iDz8l9mwNbP3nrahmg6lyzAgqH5uBqQBaRHfub1C2Rw= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9 h1:/GLQaFoLb+ciHOtAS2BIyPNnf4O5ME3AC5PUaJY9kfs= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9/go.mod h1:ABJ655C5QenQNOzf7LjCe4sSB52CXvaWLX2Zg4uwDJY= git.zhangdeman.cn/zhangdeman/trace v0.0.0-20250412104923-c1ecb1bfe8d5 h1:dD1Q/MIrRmIhKqfYPH+y167ca9CKwTPuQt3c1hXWGJ8= git.zhangdeman.cn/zhangdeman/trace v0.0.0-20250412104923-c1ecb1bfe8d5/go.mod h1:PB486NC82nuvn5yi+U2i48ogX/9EAETWAHd8O9TwY9k= git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI= @@ -67,6 +71,8 @@ github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbY github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= +github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= github.com/gin-contrib/pprof v1.5.2 h1:Kcq5W2bA2PBcVtF0MqkQjpvCpwJr+pd7zxcQh2csg7E= diff --git a/request/abstract/parse_body.go b/request/abstract/parse_body.go index 2b4a497..db381b1 100644 --- a/request/abstract/parse_body.go +++ b/request/abstract/parse_body.go @@ -7,20 +7,12 @@ // Date : 2024-10-22 16:38 package abstract -import ( - "github.com/gin-gonic/gin" -) - // RequestBodyParseAdaptor 解析请求body的接口适配器约束 // // Author : go_developer@163.com<白茶清欢> // // Date : 16:39 2024/10/22 type RequestBodyParseAdaptor interface { - // Parse 解析Body数据,解析结果会反序列化至 receiver , 同时, 会以 map 结构返回 - Parse(ctx *gin.Context, receiver any) ([]byte, error) // Unmarshal 自定义反序列化的方法, 为 nil 则使用内置的序列化方式 - Unmarshal() func(sourceData []byte, receiver any) error - // ContentType 当前适配器用与解析何种type - ContentType() string + Unmarshal(sourceData []byte, receiver any) error } diff --git a/request/parse_body/base.go b/request/parse_body/base.go deleted file mode 100644 index 792fa8f..0000000 --- a/request/parse_body/base.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package parse_body ... -// -// Description : parse_body ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2024-10-22 16:51 -package parse_body - -import ( - "bytes" - "github.com/gin-gonic/gin" - "io" -) - -type base struct { -} - -// Unmarshal 反序列化方法,可以不指定 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 16:54 2024/10/22 -func (b base) Unmarshal() func(sourceData []byte, receiver any) error { - return nil -} - -// DoParse 解析 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 17:08 2024/10/22 -func (b base) DoParse(ctx *gin.Context, receiver any, unmarshalFunc func(sourceData []byte, receiver any) error) ([]byte, error) { - data, err := io.ReadAll(ctx.Request.Body) - if nil != err { - return nil, err - } - ctx.Request.Body = io.NopCloser(bytes.NewBuffer(data)) - if nil == unmarshalFunc || nil == receiver { - return data, nil - } - if err := unmarshalFunc(data, receiver); nil != err { - return nil, err - } - return data, err -} diff --git a/request/parse_body/execute.go b/request/parse_body/execute.go index fee7d20..12eb743 100644 --- a/request/parse_body/execute.go +++ b/request/parse_body/execute.go @@ -8,9 +8,12 @@ package parse_body import ( + "bytes" "errors" "git.zhangdeman.cn/zhangdeman/gin/request/abstract" + "git.zhangdeman.cn/zhangdeman/serialize" "github.com/gin-gonic/gin" + "io" "strings" ) @@ -19,14 +22,12 @@ var ( ) func init() { - adaptorList := []abstract.RequestBodyParseAdaptor{ - JsonAdaptor{}, - FormUrlEncode{}, - XmlAdaptor{}, - } - for _, itemAdaptor := range adaptorList { - Register(itemAdaptor) - } + requestBodyParseAdaptorTable["xml"] = serialize.Xml + requestBodyParseAdaptorTable["ini"] = serialize.Ini + requestBodyParseAdaptorTable["yml"] = serialize.Yml + requestBodyParseAdaptorTable["yaml"] = serialize.Yml + requestBodyParseAdaptorTable["json"] = serialize.JSON + requestBodyParseAdaptorTable["x-www-form-urlencoded"] = serialize.JSON } // Register 注册适配器实例 @@ -34,27 +35,39 @@ func init() { // Author : go_developer@163.com<白茶清欢> // // Date : 16:45 2024/10/22 -func Register(adaptor abstract.RequestBodyParseAdaptor) { +func Register(requestType string, adaptor abstract.RequestBodyParseAdaptor) { if nil == adaptor { return } - requestBodyParseAdaptorTable[adaptor.ContentType()] = adaptor + requestBodyParseAdaptorTable[requestType] = adaptor } // Execute 解析请求BODY数据 func Execute(ctx *gin.Context, receiver any) ([]byte, error) { contentType := strings.ToLower(strings.ReplaceAll(ctx.ContentType(), " ", "")) - // 裁剪出真实的类型,之所以截取,是因为 content_type 中可能还包含编码信息, 如 : application/json;charset=utf8 + if len(contentType) == 0 { + return nil, errors.New("content_type is empty") + } + // 裁剪出真实的类型,之所以截取,是因为 content_type 中可能还包含编码信息, 如 : application/json;chaset=utf8 contentTypeArr := strings.Split(contentType, ";") + contentTypeFormatArr := strings.Split(contentTypeArr[0], "/") + if len(contentTypeFormatArr) != 2 { + return nil, errors.New(contentType + " : content_type format error") + } + // 裁剪出真实的类型,之所以截取,是因为 content_type 中可能还包含编码信息, 如 : application/json;charset=utf8 contentType = contentTypeArr[0] if _, exist := requestBodyParseAdaptorTable[contentType]; !exist { return nil, errors.New(contentType + " : adaptor not found") } - if parseResult, err := requestBodyParseAdaptorTable[contentType].Parse(ctx, receiver); nil != err { + bodyData, err := ReadBody(ctx) + if nil != err { return nil, err - } else { - return parseResult, err } + if err = requestBodyParseAdaptorTable[contentType].Unmarshal(bodyData, receiver); nil != err { + return nil, err + } + byteData := serialize.JSON.MarshalForByteIgnoreError(receiver) + return byteData, nil } // ExecuteForMap 高层级包装,表单解析为map @@ -68,3 +81,34 @@ func ExecuteForMap(ctx *gin.Context) (map[string]any, error) { } return result, nil } + +// ReadBody 读取请求Body +func ReadBody(ctx *gin.Context) ([]byte, error) { + var ( + data []byte + err error + ) + // 判断form url encode + if strings.Contains(ctx.ContentType(), "x-www-form-urlencoded") { + if err = ctx.Request.ParseForm(); nil != err { + return nil, err + } + body := map[string]any{} + for paramName, itemParam := range ctx.Request.PostForm { + if len(itemParam) > 0 { + body[paramName] = itemParam[0] + } else { + body[paramName] = "" + } + } + return serialize.JSON.MarshalForByteIgnoreError(body), nil + } + + // 读取Body信息 + if data, err = io.ReadAll(ctx.Request.Body); nil != err { + return nil, err + } + // 重置Body信息 + ctx.Request.Body = io.NopCloser(bytes.NewBuffer(data)) + return data, nil +} diff --git a/request/parse_body/form_url_encode.go b/request/parse_body/form_url_encode.go deleted file mode 100644 index a456279..0000000 --- a/request/parse_body/form_url_encode.go +++ /dev/null @@ -1,44 +0,0 @@ -// Package parse_body ... -// -// Description : parse_body ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2024-10-22 16:43 -package parse_body - -import ( - "encoding/json" - "git.zhangdeman.cn/zhangdeman/consts" - "git.zhangdeman.cn/zhangdeman/serialize" - "github.com/gin-gonic/gin" -) - -type FormUrlEncode struct { - base -} - -func (f FormUrlEncode) Parse(ctx *gin.Context, receiver any) ([]byte, error) { - if err := ctx.Request.ParseForm(); nil != err { - return nil, err - } - body := map[string]string{} - for paramName, itemParam := range ctx.Request.PostForm { - if len(itemParam) > 0 { - body[paramName] = itemParam[0] - } else { - body[paramName] = "" - } - } - byteData, _ := json.Marshal(body) - if nil != receiver { - if err := serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != receiver { - return nil, err - } - } - return byteData, nil -} - -func (f FormUrlEncode) ContentType() string { - return consts.MimeTypeXWWWFormUrlencoded -} diff --git a/request/parse_body/json.go b/request/parse_body/json.go deleted file mode 100644 index cb2301c..0000000 --- a/request/parse_body/json.go +++ /dev/null @@ -1,49 +0,0 @@ -// Package parse_body ... -// -// Description : parse_body ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2024-10-22 16:42 -package parse_body - -import ( - "git.zhangdeman.cn/zhangdeman/consts" - "git.zhangdeman.cn/zhangdeman/serialize" - "github.com/gin-gonic/gin" -) - -type JsonAdaptor struct { - base -} - -// Parse 解析json请求体 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 17:13 2024/10/22 -func (j JsonAdaptor) Parse(ctx *gin.Context, receiver any) ([]byte, error) { - unmarshalFunc := j.Unmarshal() - if nil == unmarshalFunc { - unmarshalFunc = serialize.JSON.UnmarshalWithNumber - } - return j.DoParse(ctx, receiver, unmarshalFunc) -} - -// Unmarshal 指定解析方法 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 16:56 2024/10/22 -func (j JsonAdaptor) Unmarshal() func(sourceData []byte, receiver any) error { - return serialize.JSON.UnmarshalWithNumber -} - -// ContentType 请求类型固定返回json -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 16:59 2024/10/22 -func (j JsonAdaptor) ContentType() string { - return consts.MimeTypeJson -} diff --git a/request/parse_body/xml.go b/request/parse_body/xml.go deleted file mode 100644 index 584b0a0..0000000 --- a/request/parse_body/xml.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package parse_body ... -// -// Description : parse_body ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2024-10-22 16:42 -package parse_body - -import ( - "bytes" - "git.zhangdeman.cn/zhangdeman/consts" - "git.zhangdeman.cn/zhangdeman/serialize" - "github.com/gin-gonic/gin" - "github.com/sbabiv/xml2map" -) - -type XmlAdaptor struct { - base -} - -func (x XmlAdaptor) Parse(ctx *gin.Context, receiver any) ([]byte, error) { - unmarshalFunc := x.Unmarshal() - if nil == unmarshalFunc { - unmarshalFunc = serialize.Xml.UnmarshalWithNumber - } - return x.DoParse(ctx, receiver, unmarshalFunc) -} - -func (x XmlAdaptor) Unmarshal() func(sourceData []byte, receiver any) error { - return func(sourceData []byte, receiver any) error { - res, err := xml2map.NewDecoder(bytes.NewReader(sourceData)).Decode() - if nil != err { - return err - } - return serialize.JSON.Transition(res, receiver) - } -} - -func (x XmlAdaptor) ContentType() string { - return consts.MimeTypeXml -} diff --git a/request/parse_body/yml.go b/request/parse_body/yml.go deleted file mode 100644 index 8a18ca3..0000000 --- a/request/parse_body/yml.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package parse_body ... -// -// Description : parse_body ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 2024-10-22 16:43 -package parse_body