// Package request... // // Description : 解析请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2021-07-24 8:53 下午 package request import ( "encoding/json" "io" "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) == 0 { continue } 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{} byteData []byte ) if byteData, err = io.ReadAll(ctx.Request.Body); nil != err { return make(map[string]interface{}), err } tmpResult := make(map[string][]string) orgArr := strings.Split(string(byteData), "&") for _, kvPair := range orgArr { kv := strings.Split(kvPair, "=") if len(kv) == 0 { continue } if _, exist := tmpResult[kv[0]]; !exist { tmpResult[kv[0]] = make([]string, 0) } if len(kv) == 1 { tmpResult[kv[0]] = append(tmpResult[kv[0]], "") } else { tmpResult[kv[0]] = append(tmpResult[kv[0]], strings.Join(kv[1:], "=")) } } result = make(map[string]interface{}) for k, v := range tmpResult { result[k] = v } 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 }