1. 修复formdata类型数据请求失败的问题
2. 新增发送文件的内置方法
This commit is contained in:
parent
d371cc09b3
commit
5c2d74c51d
104
README.MD
104
README.MD
@ -1,4 +1,4 @@
|
||||
# simpleRequest
|
||||
_# simpleRequest
|
||||
## 1. 说明
|
||||
[simpleRequest](www.github.com/dorlolo/simpleRequest) 是一款面向对象开发的http请求库。他是基于Go原生http库。开发这个模块的主要目的是为了更快的对接http协议的IOT设备。
|
||||
它具备以下特点:
|
||||
@ -179,9 +179,95 @@ modeldata:=demo{
|
||||
r.Body().SetModel(&modeldata)
|
||||
```
|
||||
|
||||
### 2.7 其它请求参数
|
||||
### 2.7 文件上传与转发
|
||||
### 2.7.1 文件上传
|
||||
```go
|
||||
var req = sRequest.NewRequest()
|
||||
req.Headers().ConentType_formData()
|
||||
req.Body().
|
||||
SetFromDataFile("file", "C:\\Users\\lenovo\\Pictures\\Saved Pictures\\demo.jpg").
|
||||
Set("fromFormat", "jpg").
|
||||
Set("toFormat", "png")
|
||||
req.TimeOut(15 * time.Second)
|
||||
resp, err := req.POST("http://xxx/xxx")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Println(string(resp))
|
||||
```
|
||||
### 2.7.2 文件转发
|
||||
下面示例中使用gin作为服务端,配合simpleRequest进行文件转发
|
||||
1. 通过multipart.FileHeader对象进行转发
|
||||
```go
|
||||
func FileForwardUseMultipartFile(c *gin.Context){
|
||||
file,err:=c.FormFile("file")
|
||||
|
||||
var req = sRequest.NewRequest()
|
||||
req.Headers().ConentType_formData()
|
||||
req.Body().
|
||||
SetFromDataMultipartFile("file", file).
|
||||
Set("fromFormat", "jpg").
|
||||
Set("toFormat", "png")
|
||||
req.TimeOut(15 * time.Second)
|
||||
resp, err := req.POST("http://xxx/xxx")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
// parse response and so on
|
||||
// ...
|
||||
// ...
|
||||
```
|
||||
|
||||
#### 2.7.1 设置超时时间
|
||||
2. 在一些小众场景下,可能已经在外部构建好了body,此时也可将body转为bytes传入simpleRequest进行请求
|
||||
```go
|
||||
func FileForwardUseBytesBody(c *gin.Context){
|
||||
file,err:=c.FormFile("file")
|
||||
|
||||
// body data prepare
|
||||
vars (
|
||||
body = &bytes.Buffer{}
|
||||
writer = multipart.NewWriter(body)
|
||||
)
|
||||
// add file object
|
||||
filePart, _ := i.writer.CreateFormFile("file", file.Filename)
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
fmt.Println( err.Error())
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
_, err = io.Copy(filePart, src)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
// add other form data
|
||||
writer.WriteField("fromFormat", "jpg")
|
||||
writer.WriteField("toFormat","png")
|
||||
|
||||
// post request
|
||||
_ = writer.close()
|
||||
var r = simpleRequest.NewRequest()
|
||||
req.Headers().SetConentType(writer.FormDataContentType())
|
||||
req.Body().SetBytes(body.Bytes())
|
||||
req.TimeOut(15 * time.Second)
|
||||
resp, err := req.POST("http://xxx/xxx")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
// parse response and so on
|
||||
// ...
|
||||
// ...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 2.8 其它请求参数
|
||||
|
||||
#### 2.8.1 设置超时时间
|
||||
```go
|
||||
r.TimeOut(time.Second * 30)
|
||||
```
|
||||
@ -191,8 +277,8 @@ r.TimeOut(time.Second * 30)
|
||||
r.SkipCertVerify()
|
||||
```
|
||||
|
||||
### 2.8 发送请求
|
||||
#### 2.8.1 post请求
|
||||
### 2.9 发送请求
|
||||
#### 2.9.1 post请求
|
||||
```go
|
||||
res, err :=r.POST("https://127.0.0.1:80/excample")
|
||||
if err != nil {
|
||||
@ -213,17 +299,17 @@ if err != nil {
|
||||
- TRACE
|
||||
|
||||
|
||||
### 2.9 获取上下文
|
||||
### 2.10 获取上下文
|
||||
请注意,需要完成请求后才能获得上下文数据!
|
||||
#### 2.9.1 获取请求的上下文对象
|
||||
#### 2.10.1 获取请求的上下文对象
|
||||
```go
|
||||
requestContext:=r.Request
|
||||
```
|
||||
|
||||
#### 2.9.2 获取返回的上下文对象
|
||||
#### 2.10.2 获取返回的上下文对象
|
||||
```go
|
||||
responseContext:=r.Response
|
||||
```
|
||||
|
||||
## 3. 使用示例
|
||||
[simpleRequest_test.go](excample/simpleRequest_test.go)
|
||||
[simpleRequest_test.go](excample/simpleRequest_test.go)_
|
22
body.go
22
body.go
@ -7,6 +7,8 @@
|
||||
|
||||
package simpleRequest
|
||||
|
||||
import "mime/multipart"
|
||||
|
||||
// EntryMark 请求体条目标记,用于标记输入的body内容格式
|
||||
type EntryMark string
|
||||
|
||||
@ -15,10 +17,12 @@ func (b EntryMark) string() string {
|
||||
}
|
||||
|
||||
const (
|
||||
StringEntryType EntryMark = "__STRING_ENTRY__"
|
||||
BytesEntryType EntryMark = "__BYTES_ENTRY__"
|
||||
ModelEntryType EntryMark = "__MODEL_ENTRY__"
|
||||
MapEntryType EntryMark = "__MAP_ENTRY__"
|
||||
StringEntryType EntryMark = "__STRING_ENTRY__"
|
||||
BytesEntryType EntryMark = "__BYTES_ENTRY__"
|
||||
ModelEntryType EntryMark = "__MODEL_ENTRY__"
|
||||
MapEntryType EntryMark = "__MAP_ENTRY__"
|
||||
MultipartEntryType EntryMark = "__MULTIPART_ENTRY__"
|
||||
FormFilePathKey EntryMark = "__FORM_FILE_PATH_KEY__"
|
||||
)
|
||||
|
||||
type BodyConf struct {
|
||||
@ -53,3 +57,13 @@ func (s *BodyConf) SetModel(model any) *BodyConf {
|
||||
s.simpleReq.BodyEntries[ModelEntryType.string()] = model
|
||||
return s
|
||||
}
|
||||
func (s *BodyConf) SetFromDataFile(key, filePath string) *BodyConf {
|
||||
s.simpleReq.BodyEntryMark = MultipartEntryType
|
||||
s.simpleReq.BodyEntries[FormFilePathKey.string()+key] = filePath
|
||||
return s
|
||||
}
|
||||
func (s *BodyConf) SetFromDataMultipartFile(key string, multFile *multipart.FileHeader) *BodyConf {
|
||||
s.simpleReq.BodyEntryMark = MultipartEntryType
|
||||
s.simpleReq.BodyEntries[key] = multFile
|
||||
return s
|
||||
}
|
||||
|
52
parser.go
52
parser.go
@ -1,4 +1,4 @@
|
||||
// Package simpleRequest -----------------------------
|
||||
// Package sRequest -----------------------------
|
||||
// file : parser.go
|
||||
// author : JJXu
|
||||
// contact : wavingBear@163.com
|
||||
@ -11,6 +11,8 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -76,31 +78,55 @@ func (f *FormDataParser) Unmarshal(bodyType EntryMark, BodyEntry map[string]any)
|
||||
}
|
||||
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[BytesEntryType.string()].([]byte))
|
||||
default:
|
||||
body, f.ContentType = multipartCommonParse(BodyEntry)
|
||||
}
|
||||
f.ContentType = formDataType
|
||||
return nil
|
||||
return
|
||||
}
|
||||
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)
|
||||
if strings.Contains(k, FormFilePathKey.string()) {
|
||||
key := k[len(FormFilePathKey):]
|
||||
path := sv.(string)
|
||||
filename := filepath.Base(path)
|
||||
filePart, _ := writer.CreateFormFile(key, filename)
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, _ = filePart.Write(content)
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
case *multipart.FileHeader:
|
||||
file, _ := sv.(*multipart.FileHeader)
|
||||
filePart, _ := writer.CreateFormFile(k, file.Filename)
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
_, err = io.Copy(filePart, src)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
err := writer.Close()
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user