升级body解析

This commit is contained in:
2025-05-04 14:36:26 +08:00
parent 146fbaf878
commit 2aa8e86917
9 changed files with 67 additions and 214 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -1,8 +0,0 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:43
package parse_body