新增bodyentry解析模块,可自定义解析函数
This commit is contained in:
parent
9bff109127
commit
f0327d0c93
@ -90,7 +90,7 @@ r.QueryParams().Set("user", "dorlolo")
|
||||
#### 2.4.2 map赋值
|
||||
不会覆盖上面之前填充过的参数
|
||||
```go
|
||||
pamarsBulid := make(map[string]interface{})
|
||||
pamarsBulid := make(map[string]any)
|
||||
pamarsBulid["passwd"] = "123456"
|
||||
pamarsBulid["action"] = "login"
|
||||
r.QueryParams().Sets(pamarsBulid)
|
||||
@ -118,7 +118,7 @@ r.Body().Set("beginDate", "2022-03-01").Set("endDate", "2022-03-03")
|
||||
|
||||
#### 2.5.2 map赋值
|
||||
```go
|
||||
bodyBulid := map[string]interface{}{
|
||||
bodyBulid := map[string]any{
|
||||
"beginDate":"2022-03-01",
|
||||
"endDate":"2022-03-03",
|
||||
}
|
||||
|
37
body.go
37
body.go
@ -7,25 +7,48 @@
|
||||
|
||||
package simpleRequest
|
||||
|
||||
var (
|
||||
stringBodyType = "__STRING_BODY__"
|
||||
type EntryMark string
|
||||
|
||||
func (b EntryMark) string() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
const (
|
||||
StringEntryType EntryMark = "__STRING_ENTRY__"
|
||||
BytesEntryType EntryMark = "__BYTES_ENTRY__"
|
||||
ModelEntryType EntryMark = "__MODEL_ENTRY__"
|
||||
MapEntryType EntryMark = "__MAP_ENTRY__"
|
||||
)
|
||||
|
||||
type BodyConf struct {
|
||||
simpleReq *SimpleRequest
|
||||
}
|
||||
|
||||
func (s *BodyConf) Set(key string, value interface{}) *BodyConf {
|
||||
s.simpleReq.tempBody[key] = value
|
||||
func (s *BodyConf) Set(key string, value any) *BodyConf {
|
||||
s.simpleReq.BodyEntries[key] = value
|
||||
return s
|
||||
}
|
||||
func (s *BodyConf) Sets(data map[string]interface{}) *BodyConf {
|
||||
func (s *BodyConf) Sets(data map[string]any) *BodyConf {
|
||||
s.simpleReq.BodyEntryMark = MapEntryType
|
||||
for k, v := range data {
|
||||
s.simpleReq.tempBody[k] = v
|
||||
s.simpleReq.BodyEntries[k] = v
|
||||
}
|
||||
return s
|
||||
}
|
||||
func (s *BodyConf) SetString(strData string) *BodyConf {
|
||||
s.simpleReq.tempBody[stringBodyType] = strData
|
||||
s.simpleReq.BodyEntryMark = StringEntryType
|
||||
s.simpleReq.BodyEntries[StringEntryType.string()] = strData
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BodyConf) SetBytes(byteData []byte) *BodyConf {
|
||||
s.simpleReq.BodyEntryMark = BytesEntryType
|
||||
s.simpleReq.BodyEntries[BytesEntryType.string()] = byteData
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BodyConf) SetModel(model any) *BodyConf {
|
||||
s.simpleReq.BodyEntryMark = ModelEntryType
|
||||
s.simpleReq.BodyEntries[ModelEntryType.string()] = model
|
||||
return s
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func TestRequest(t *testing.T) {
|
||||
//设置params
|
||||
r.QueryParams().Set("user", "dorlolo")
|
||||
//批量添加,不会覆盖上面user
|
||||
pamarsBulid := map[string]interface{}{
|
||||
pamarsBulid := map[string]any{
|
||||
"passwd": "123456",
|
||||
"action": "login",
|
||||
}
|
||||
|
10
headers.go
10
headers.go
@ -9,7 +9,6 @@ package simpleRequest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"regexp"
|
||||
@ -36,7 +35,7 @@ var (
|
||||
|
||||
jsonCheck = regexp.MustCompile(`(?i:(application|text)/(json|.*\+json|json\-.*)(;|$))`)
|
||||
xmlCheck = regexp.MustCompile(`(?i:(application|text)/(xml|.*\+xml)(;|$))`)
|
||||
bufPool = &sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
||||
bufPool = &sync.Pool{New: func() any { return &bytes.Buffer{} }}
|
||||
)
|
||||
|
||||
var userAgentList = [...]string{
|
||||
@ -101,11 +100,6 @@ func (s *HeadersConf) SetConentType(value string) *HeadersConf {
|
||||
}
|
||||
|
||||
func (s *HeadersConf) ConentType_json() *HeadersConf {
|
||||
jsonData, err := json.Marshal(s.simpleReq.tempBody)
|
||||
if err == nil {
|
||||
s.simpleReq.body = bytes.NewReader([]byte("{}"))
|
||||
}
|
||||
s.simpleReq.body = bytes.NewReader(jsonData)
|
||||
s.simpleReq.headers.Set(hdrContentTypeKey, jsonContentType)
|
||||
return s
|
||||
}
|
||||
@ -118,7 +112,7 @@ func (s *HeadersConf) ConentType_charsetUtf8() *HeadersConf {
|
||||
func (s *HeadersConf) ConentType_formData() *HeadersConf {
|
||||
//tmp := url.Values{}
|
||||
|
||||
//for k, v := range s.simpleReq.tempBody {
|
||||
//for k, v := range s.simpleReq.BodyEntry {
|
||||
// tmp.Add(k, fmt.Sprintf("%v", v))
|
||||
//}
|
||||
s.simpleReq.headers.Set(hdrContentTypeKey, formDataType)
|
||||
|
17
options.go
Normal file
17
options.go
Normal file
@ -0,0 +1,17 @@
|
||||
// Package simpleRequest -----------------------------
|
||||
// @file : options.go
|
||||
// @author : JJXu
|
||||
// @contact : wavingBear@163.com
|
||||
// @time : 2022/12/10 01:45:37
|
||||
// -------------------------------------------
|
||||
package simpleRequest
|
||||
|
||||
type OPTION func(r *SimpleRequest) *SimpleRequest
|
||||
|
||||
//OptionNewBodyEntryParser 新增或覆盖BodyEntryParser
|
||||
func OptionNewBodyEntryParser(contentType string, parser IBodyEntryParser) OPTION {
|
||||
return func(r *SimpleRequest) *SimpleRequest {
|
||||
r.bodyEntryParsers[contentType] = parser
|
||||
return r
|
||||
}
|
||||
}
|
4
param.go
4
param.go
@ -17,7 +17,7 @@ type QueryParams struct {
|
||||
}
|
||||
|
||||
//batch settings
|
||||
func (s *QueryParams) Sets(data map[string]interface{}) *QueryParams {
|
||||
func (s *QueryParams) Sets(data map[string]any) *QueryParams {
|
||||
for k, v := range data {
|
||||
s.simpleReq.queryParams.Set(k, fmt.Sprintf("%v", v))
|
||||
}
|
||||
@ -25,7 +25,7 @@ func (s *QueryParams) Sets(data map[string]interface{}) *QueryParams {
|
||||
}
|
||||
|
||||
//single settings
|
||||
func (s *QueryParams) Set(key string, value interface{}) *QueryParams {
|
||||
func (s *QueryParams) Set(key string, value any) *QueryParams {
|
||||
s.simpleReq.queryParams.Set(key, fmt.Sprintf("%v", value))
|
||||
return s
|
||||
}
|
||||
|
111
parser.go
Normal file
111
parser.go
Normal file
@ -0,0 +1,111 @@
|
||||
// Package simpleRequest -----------------------------
|
||||
// @file : parser.go
|
||||
// @author : JJXu
|
||||
// @contact : wavingBear@163.com
|
||||
// @time : 2022/12/10 00:48:45
|
||||
// -------------------------------------------
|
||||
package simpleRequest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var bodyEntryParsers = map[string]IBodyEntryParser{
|
||||
jsonContentType: new(JsonParser),
|
||||
formDataType: new(FormDataParser),
|
||||
}
|
||||
|
||||
type IBodyEntryParser interface {
|
||||
Unmarshal(bodyType EntryMark, BodyEntry map[string]any) io.Reader
|
||||
}
|
||||
|
||||
type JsonParser struct{}
|
||||
|
||||
func (JsonParser) Unmarshal(bodyType EntryMark, BodyEntry map[string]any) io.Reader {
|
||||
switch bodyType {
|
||||
case StringEntryType:
|
||||
return strings.NewReader(BodyEntry[StringEntryType.string()].(string))
|
||||
case BytesEntryType:
|
||||
return bytes.NewReader(BodyEntry[BytesEntryType.string()].([]byte))
|
||||
case ModelEntryType:
|
||||
jsonData, err := json.Marshal(BodyEntry)
|
||||
if err == nil {
|
||||
return bytes.NewReader(jsonData)
|
||||
} else {
|
||||
return strings.NewReader("{}")
|
||||
}
|
||||
case MapEntryType:
|
||||
jsonData, err := json.Marshal(BodyEntry)
|
||||
if err == nil {
|
||||
return bytes.NewReader(jsonData)
|
||||
} else {
|
||||
return strings.NewReader("{}")
|
||||
}
|
||||
default:
|
||||
if len(BodyEntry) > 0 {
|
||||
jsonData, err := json.Marshal(BodyEntry)
|
||||
if err == nil {
|
||||
return bytes.NewReader(jsonData)
|
||||
}
|
||||
}
|
||||
return strings.NewReader("{}")
|
||||
}
|
||||
}
|
||||
|
||||
type FormDataParser struct {
|
||||
ContentType string
|
||||
}
|
||||
|
||||
func (f *FormDataParser) Unmarshal(bodyType EntryMark, BodyEntry map[string]any) (body io.Reader) {
|
||||
switch bodyType {
|
||||
case MapEntryType:
|
||||
body, f.ContentType = multipartCommonParse(BodyEntry)
|
||||
case ModelEntryType:
|
||||
tb := BodyEntry[ModelEntryType.string()]
|
||||
buffer, err := json.Marshal(tb)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
var mapper map[string]any
|
||||
err = json.Unmarshal(buffer, &mapper)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
body, f.ContentType = multipartCommonParse(mapper)
|
||||
case StringEntryType:
|
||||
f.ContentType = formDataType
|
||||
return strings.NewReader(BodyEntry[StringEntryType.string()].(string))
|
||||
case BytesEntryType:
|
||||
f.ContentType = formDataType
|
||||
return bytes.NewReader(BodyEntry[StringEntryType.string()].([]byte))
|
||||
default:
|
||||
body, f.ContentType = multipartCommonParse(BodyEntry)
|
||||
}
|
||||
f.ContentType = formDataType
|
||||
return nil
|
||||
}
|
||||
func multipartCommonParse(BodyEntry map[string]any) (reader io.Reader, contentType string) {
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
for k, sv := range BodyEntry {
|
||||
switch sv.(type) {
|
||||
case string:
|
||||
strSv, _ := sv.(string)
|
||||
_ = writer.WriteField(k, strSv)
|
||||
case []string:
|
||||
sss, _ := sv.([]string)
|
||||
for _, v := range sss {
|
||||
_ = writer.WriteField(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
err := writer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return body, writer.FormDataContentType()
|
||||
}
|
122
simpleRequest.go
122
simpleRequest.go
@ -8,33 +8,37 @@
|
||||
package simpleRequest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewRequest() *SimpleRequest {
|
||||
func NewRequest(opts ...OPTION) *SimpleRequest {
|
||||
var (
|
||||
hd = http.Header{}
|
||||
qp = url.Values{}
|
||||
)
|
||||
|
||||
return &SimpleRequest{
|
||||
var r = &SimpleRequest{
|
||||
//headers: make(map[string]string),
|
||||
//cookies: make(map[string]string),
|
||||
timeout: time.Second * 7,
|
||||
queryParams: qp,
|
||||
headers: hd,
|
||||
tempBody: make(map[string]interface{}),
|
||||
timeout: time.Second * 7,
|
||||
queryParams: qp,
|
||||
headers: hd,
|
||||
BodyEntries: make(map[string]any),
|
||||
bodyEntryParsers: bodyEntryParsers,
|
||||
}
|
||||
if len(opts) > 0 {
|
||||
for _, o := range opts {
|
||||
r = o(r)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type SimpleRequest struct {
|
||||
@ -44,13 +48,16 @@ type SimpleRequest struct {
|
||||
headers http.Header
|
||||
transport *http.Transport
|
||||
|
||||
tempBody map[string]interface{}
|
||||
timeout time.Duration
|
||||
BodyEntryMark EntryMark
|
||||
BodyEntries map[string]any
|
||||
bodyEntryParsers map[string]IBodyEntryParser
|
||||
|
||||
timeout time.Duration
|
||||
|
||||
Response http.Response //用于获取完整的返回内容。请注意要在请求之后才能获取
|
||||
Request http.Request //用于获取完整的请求内容。请注意要在请求之后才能获取
|
||||
//cookies map[string]string
|
||||
//data interface{}
|
||||
//data any
|
||||
//cli *http.Client
|
||||
//debug bool
|
||||
//method string
|
||||
@ -62,16 +69,16 @@ type SimpleRequest struct {
|
||||
//checkRedirect func(req *http.Request, via []*http.Request) error
|
||||
}
|
||||
|
||||
func (s *SimpleRequest) NewRequest() *SimpleRequest {
|
||||
var qp = url.Values{}
|
||||
return &SimpleRequest{
|
||||
//headers: make(map[string]string),
|
||||
//cookies: make(map[string]string),
|
||||
timeout: time.Second * 7,
|
||||
queryParams: qp,
|
||||
tempBody: make(map[string]interface{}),
|
||||
}
|
||||
}
|
||||
//func (s *SimpleRequest) NewRequest() *SimpleRequest {
|
||||
// var qp = url.Values{}
|
||||
// return &SimpleRequest{
|
||||
// //headers: make(map[string]string),
|
||||
// //cookies: make(map[string]string),
|
||||
// timeout: time.Second * 7,
|
||||
// queryParams: qp,
|
||||
// BodyEntries: make(map[string]any),
|
||||
// }
|
||||
//}
|
||||
|
||||
//------------------------------------------------------
|
||||
//
|
||||
@ -258,49 +265,50 @@ func (s *SimpleRequest) initBody() {
|
||||
contentTypeData := s.headers.Get(hdrContentTypeKey)
|
||||
switch {
|
||||
case IsJSONType(contentTypeData):
|
||||
jsonData, err := json.Marshal(s.tempBody)
|
||||
if err == nil {
|
||||
s.body = bytes.NewReader(jsonData)
|
||||
} else {
|
||||
s.body = bytes.NewReader([]byte("{}"))
|
||||
var parser, ok = s.bodyEntryParsers[jsonContentType]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("cannot find %s type parser", contentTypeData))
|
||||
}
|
||||
case strings.Contains(contentTypeData, "multipart/form-data"):
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
//data := url.Values{}
|
||||
for k, sv := range s.tempBody {
|
||||
switch sv.(type) {
|
||||
case string:
|
||||
strSv, _ := sv.(string)
|
||||
_ = writer.WriteField(k, strSv)
|
||||
case []string:
|
||||
sss, _ := sv.([]string)
|
||||
for _, v := range sss {
|
||||
_ = writer.WriteField(k, v)
|
||||
}
|
||||
}
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
|
||||
case strings.Contains(contentTypeData, formDataType):
|
||||
var parser, ok = s.bodyEntryParsers[formDataType]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("cannot find %s type parser", contentTypeData))
|
||||
}
|
||||
err := writer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.headers.Set("Content-Type", writer.FormDataContentType())
|
||||
s.body = body
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
fdParser := parser.(*FormDataParser)
|
||||
s.headers.Set("Content-Type", fdParser.ContentType)
|
||||
|
||||
case IsXMLType(contentTypeData):
|
||||
//application/soap+xml ,application/xml
|
||||
data, _ := s.tempBody[stringBodyType].(string)
|
||||
s.body = strings.NewReader(data)
|
||||
var parser, ok = s.bodyEntryParsers[xmlDataType]
|
||||
if !ok {
|
||||
data, _ := s.BodyEntries[StringEntryType.string()].(string)
|
||||
s.body = strings.NewReader(data)
|
||||
}
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
|
||||
case strings.Contains(contentTypeData, "text") || strings.Contains(contentTypeData, javaScriptType):
|
||||
data, _ := s.tempBody[stringBodyType].(string)
|
||||
s.body = strings.NewReader(data)
|
||||
var parser, ok = s.bodyEntryParsers[textPlainType]
|
||||
if !ok {
|
||||
data, _ := s.BodyEntries[StringEntryType.string()].(string)
|
||||
s.body = strings.NewReader(data)
|
||||
}
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
|
||||
case contentTypeData == "" || strings.Contains(contentTypeData, "form-urlencoded"):
|
||||
//默认为x-www-form-urlencoded格式
|
||||
tmpData := url.Values{}
|
||||
for k, v := range s.tempBody {
|
||||
tmpData.Set(k, fmt.Sprintf("%v", v))
|
||||
var parser, ok = s.bodyEntryParsers["form-urlencoded"]
|
||||
if !ok {
|
||||
tmpData := url.Values{}
|
||||
for k, v := range s.BodyEntries {
|
||||
tmpData.Set(k, fmt.Sprintf("%v", v))
|
||||
}
|
||||
s.body = strings.NewReader(tmpData.Encode())
|
||||
s.Headers().ConentType_formUrlencoded()
|
||||
}
|
||||
s.body = strings.NewReader(tmpData.Encode())
|
||||
s.Headers().ConentType_formUrlencoded()
|
||||
s.body = parser.Unmarshal(s.BodyEntryMark, s.BodyEntries)
|
||||
default:
|
||||
//todo 自动判断数据类型
|
||||
tmpData := url.Values{}
|
||||
|
@ -57,7 +57,7 @@ func TestPost_withSets(t *testing.T) {
|
||||
|
||||
var r = NewRequest()
|
||||
r.Headers().ConentType_json()
|
||||
r.Body().Sets(map[string]interface{}{
|
||||
r.Body().Sets(map[string]any{
|
||||
"name": "JJXu",
|
||||
})
|
||||
result, err := r.POST("http://localhost:8989/")
|
||||
|
Loading…
Reference in New Issue
Block a user