Skip to content

Commit 1d93dc6

Browse files
authored
Set xxx ex (#339)
* 支持绑定多个对象 * 使用低版本有的api
1 parent d2a1791 commit 1d93dc6

File tree

6 files changed

+107
-15
lines changed

6 files changed

+107
-15
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ gout 是go写的http 客户端,为提高工作效率而开发
6767
- [protobuf](#protobuf)
6868
- [callback](#callback)
6969
- [get *http.Response](#get-response)
70+
- [multiple binding functions](#multiple-binding-functions)
7071
- [Set request timeout](#Set-request-timeout)
7172
- [proxy](#proxy)
7273
- [socks5](#socks5)
@@ -1118,6 +1119,31 @@ func main() {
11181119
}
11191120
}
11201121
1122+
```
1123+
### multiple binding functions
1124+
支持绑定多个对象
1125+
```go
1126+
var responseStruct struct {
1127+
Name string `json:"name"`
1128+
Age int `json:"age"`
1129+
}
1130+
1131+
func main() {
1132+
1133+
var responseStr string
1134+
err := gout.GET("url").
1135+
SetQuery(gout.H{}).
1136+
BindJSON(&responseStruct).
1137+
BindBody(&responseStr).
1138+
Do()
1139+
1140+
if err != nil {
1141+
return
1142+
}
1143+
1144+
log.Println(responseStr)
1145+
}
1146+
11211147
```
11221148
## Set request timeout
11231149
setimeout是request级别的超时方案。相比http.Client级别,更灵活。

dataflow/dataflow.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,33 +296,44 @@ func (df *DataFlow) BindHeader(obj interface{}) *DataFlow {
296296
// BindBody parse the variables in http body to obj.
297297
// obj must be a pointer variable
298298
func (df *DataFlow) BindBody(obj interface{}) *DataFlow {
299-
300-
df.Req.bodyDecoder = decode.NewBodyDecode(obj)
299+
if obj == nil {
300+
return df
301+
}
302+
df.Req.bodyDecoder = append(df.Req.bodyDecoder, decode.NewBodyDecode(obj))
301303
return df
302304
}
303305

304306
// BindJSON parse the json string in http body to obj.
305307
// obj must be a pointer variable
306308
func (df *DataFlow) BindJSON(obj interface{}) *DataFlow {
309+
if obj == nil {
310+
return df
311+
}
307312
df.out.opt.RspBodyType = "json"
308-
df.Req.bodyDecoder = decode.NewJSONDecode(obj)
313+
df.Req.bodyDecoder = append(df.Req.bodyDecoder, decode.NewJSONDecode(obj))
309314
return df
310315

311316
}
312317

313318
// BindYAML parse the yaml string in http body to obj.
314319
// obj must be a pointer variable
315320
func (df *DataFlow) BindYAML(obj interface{}) *DataFlow {
321+
if obj == nil {
322+
return df
323+
}
316324
df.out.opt.RspBodyType = "yaml"
317-
df.Req.bodyDecoder = decode.NewYAMLDecode(obj)
325+
df.Req.bodyDecoder = append(df.Req.bodyDecoder, decode.NewYAMLDecode(obj))
318326
return df
319327
}
320328

321329
// BindXML parse the xml string in http body to obj.
322330
// obj must be a pointer variable
323331
func (df *DataFlow) BindXML(obj interface{}) *DataFlow {
332+
if obj == nil {
333+
return df
334+
}
324335
df.out.opt.RspBodyType = "xml"
325-
df.Req.bodyDecoder = decode.NewXMLDecode(obj)
336+
df.Req.bodyDecoder = append(df.Req.bodyDecoder, decode.NewXMLDecode(obj))
326337
return df
327338
}
328339

dataflow/dataflow_body_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,31 @@ func TestSetBody(t *testing.T) {
241241
assert.NoError(t, err)
242242
assert.Equal(t, code, 200)
243243
}
244+
245+
// 同时绑定json, body
246+
func TestBindBodyJSON(t *testing.T) {
247+
router := gin.New()
248+
249+
router.GET("", func(c *gin.Context) {
250+
c.JSON(200, gin.H{"code": 1})
251+
})
252+
253+
ts := httptest.NewServer(http.HandlerFunc(router.ServeHTTP))
254+
defer ts.Close()
255+
256+
type body struct {
257+
Code int
258+
}
259+
260+
gotJson := body{}
261+
s := ""
262+
263+
err := GET(ts.URL).BindJSON(&gotJson).BindBody(&s).Do()
264+
assert.NoError(t, err)
265+
assert.Equal(t, body{Code: 1}, gotJson)
266+
assert.Equal(t, `{"code":1}`, s)
267+
}
268+
244269
func TestBindBody(t *testing.T) {
245270
router := func() *gin.Engine {
246271
router := gin.New()
@@ -290,6 +315,7 @@ func TestBindBody(t *testing.T) {
290315
}()
291316

292317
ts := httptest.NewServer(http.HandlerFunc(router.ServeHTTP))
318+
defer ts.Close()
293319

294320
tests := []testBodyReq{
295321
{url: "/uint", got: new(uint), need: core.NewPtrVal(uint(1))},

dataflow/debug.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ func (do *DebugOption) resetBodyAndPrint(req *http.Request, resp *http.Response)
7373
return err
7474
}
7575

76+
resp.Body.Close()
77+
7678
resp.Body = ioutil.NopCloser(bytes.NewReader(all))
7779
err = do.debugPrint(req, resp)
7880
resp.Body = ioutil.NopCloser(bytes.NewReader(all))

dataflow/req.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Req struct {
3535

3636
// http body
3737
bodyEncoder encode.Encoder
38-
bodyDecoder decode.Decoder
38+
bodyDecoder []decode.Decoder
3939

4040
// http header
4141
headerEncode []interface{}
@@ -375,6 +375,34 @@ func (r *Req) GetContext() context.Context {
375375
return r.c
376376
}
377377

378+
// TODO 优化代码,每个decode都有自己的指针偏移直接指向流,减少大body的内存使用
379+
func (r *Req) decodeBody(req *http.Request, resp *http.Response) (err error) {
380+
381+
if r.bodyDecoder != nil {
382+
var all []byte
383+
if len(r.bodyDecoder) > 1 {
384+
all, err = ioutil.ReadAll(resp.Body)
385+
if err != nil {
386+
return err
387+
}
388+
//已经取走数据,直接关闭body
389+
resp.Body.Close()
390+
}
391+
392+
for _, bodyDecoder := range r.bodyDecoder {
393+
if len(all) > 0 {
394+
resp.Body = ioutil.NopCloser(bytes.NewReader(all))
395+
}
396+
397+
if err = bodyDecoder.Decode(resp.Body); err != nil {
398+
return err
399+
}
400+
}
401+
}
402+
403+
return nil
404+
}
405+
378406
func (r *Req) decode(req *http.Request, resp *http.Response, openDebug bool) (err error) {
379407
defer func() {
380408
if err == io.EOF {
@@ -412,13 +440,7 @@ func (r *Req) decode(req *http.Request, resp *http.Response, openDebug bool) (er
412440
}
413441
}
414442

415-
if r.bodyDecoder != nil {
416-
if err = r.bodyDecoder.Decode(resp.Body); err != nil {
417-
return err
418-
}
419-
}
420-
421-
return nil
443+
return r.decodeBody(req, resp)
422444
}
423445

424446
func (r *Req) getDataFlow() *DataFlow {
@@ -539,8 +561,13 @@ func (r *Req) Do() (err error) {
539561
}
540562

541563
if r.bodyDecoder != nil {
542-
return valid.ValidateStruct(r.bodyDecoder.Value())
564+
for _, bodyDecoder := range r.bodyDecoder {
565+
if err := valid.ValidateStruct(bodyDecoder.Value()); err != nil {
566+
return err
567+
}
568+
}
543569
}
570+
544571
return nil
545572
}
546573

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
package gout
22

33
// Version show version
4-
const Version = "v0.2.10"
4+
const Version = "v0.3.0"

0 commit comments

Comments
 (0)