gopkg/gin/request/util.go

176 lines
4.7 KiB
Go

// Package request...
//
// Description : 解析请求
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-07-24 8:53 下午
package request
import (
"encoding/json"
"net/http"
"net/url"
"strings"
"git.zhangdeman.cn/zhangdeman/gopkg/util"
"github.com/gin-gonic/gin"
)
// ParseRequestParam 解析请求数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:52 下午 2021/9/14
func ParseRequestParam(ctx *gin.Context) (map[string]interface{}, error) {
switch ctx.Request.Method {
case http.MethodPost:
return ParsePostRequestBody(ctx)
default:
return ParseGetRequestBody(ctx)
}
}
// ParseGetRequestURI 解析URL请求参数
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 9:03 下午 2021/7/24
func ParseGetRequestURI(url *url.URL) map[string][]string {
url.RawQuery = strings.TrimSpace(url.RawQuery)
parseResult := make(map[string][]string)
if len(url.RawQuery) == 0 {
return parseResult
}
requestURIArr := strings.Split(url.RawQuery, "&")
for _, kvPair := range requestURIArr {
kvPair = strings.TrimSpace(kvPair)
if len(kvPair) == 0 {
continue
}
kvArr := strings.Split(kvPair, "=")
_, keyExist := parseResult[kvArr[0]]
if len(kvArr) == 1 {
// 识别到 ?a=1&b=2&c 这种格式,默认补齐成 ?a=1&b=2&c=
if keyExist {
parseResult[kvPair] = append(parseResult[kvPair], "")
} else {
parseResult[kvPair] = []string{""}
}
continue
}
// 兼容参数值中包含=的情况
if keyExist {
parseResult[kvArr[0]] = append(parseResult[kvArr[0]], strings.Join(kvArr[1:], "="))
} else {
parseResult[kvArr[0]] = []string{strings.Join(kvArr[1:], "=")}
}
}
return parseResult
}
// ParseGetRequestBody 解析get请求的body
//
// Author : zhangdeman001@ke.com<白茶清欢>
//
// Date : 9:07 下午 2021/7/24
func ParseGetRequestBody(ctx *gin.Context) (map[string]interface{}, error) {
result := make(map[string]interface{})
urlRaw := strings.TrimLeft(ctx.Request.URL.RawQuery, "/")
queryArr := strings.Split(urlRaw, "&")
for _, itemPair := range queryArr {
itemPairArr := strings.Split(itemPair, "=")
if len(itemPairArr) == 1 {
result[itemPairArr[0]] = ""
} else {
result[itemPairArr[0]] = strings.Join(itemPairArr[1:], "=")
}
}
return result, nil
}
// ParsePostRequestBody 解析post请求参数
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 7:38 下午 2021/9/14
func ParsePostRequestBody(ctx *gin.Context) (map[string]interface{}, error) {
contentType := strings.ToLower(ctx.ContentType())
if strings.Contains(contentType, "application/json") {
// application/json 请求参数
return ParsePostRequestForApplicationJSON(ctx)
}
if strings.Contains(contentType, "x-www-form-urlencoded") {
// Content-Type: application/x-www-form-urlencoded 请求方法
return ParsePostRequestForApplicationFormURLEncoded(ctx)
}
if strings.Contains(contentType, "form-data") {
// multipart/form-data 请求方法
return ParsePostRequestForFormData(ctx)
}
return make(map[string]interface{}), nil
}
// ParsePostRequestForApplicationJSON 解析application/json请求
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:00 下午 2021/9/14
func ParsePostRequestForApplicationJSON(ctx *gin.Context) (map[string]interface{}, error) {
var (
err error
result map[string]interface{}
)
decoder := json.NewDecoder(ctx.Request.Body)
decoder.UseNumber()
if err = decoder.Decode(&result); nil != err {
return make(map[string]interface{}), err
}
return result, nil
}
// ParsePostRequestForApplicationFormURLEncoded 解析 application/x-www-form-urlencoded 表单
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:11 下午 2021/9/14
func ParsePostRequestForApplicationFormURLEncoded(ctx *gin.Context) (map[string]interface{}, error) {
var (
err error
result map[string]interface{}
)
if err = ctx.Request.ParseForm(); nil != err {
return make(map[string]interface{}), err
}
if err = util.JSONUnmarshalWithNumberForIOReader(ctx.Request.Body, &result); nil != err {
return make(map[string]interface{}), err
}
return result, err
}
// ParsePostRequestForFormData 解析 multipart/form-data 表单数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:17 下午 2021/9/14
func ParsePostRequestForFormData(ctx *gin.Context) (map[string]interface{}, error) {
var (
err error
result map[string]interface{}
)
if err = ctx.Request.ParseMultipartForm(32 << 20); nil != err {
return make(map[string]interface{}), err
}
if err = ctx.Request.ParseForm(); nil != err {
return make(map[string]interface{}), err
}
if err = util.JSONUnmarshalWithNumberForIOReader(ctx.Request.Body, &result); nil != err {
return make(map[string]interface{}), err
}
return result, nil
}