mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-14 18:30:02 +08:00
feat: support json array in request body (#4444)
This commit is contained in:
@@ -3,6 +3,7 @@ package httpx
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
@@ -43,6 +44,8 @@ type Validator interface {
|
|||||||
|
|
||||||
// Parse parses the request.
|
// Parse parses the request.
|
||||||
func Parse(r *http.Request, v any) error {
|
func Parse(r *http.Request, v any) error {
|
||||||
|
kind := mapping.Deref(reflect.TypeOf(v)).Kind()
|
||||||
|
if kind != reflect.Array && kind != reflect.Slice {
|
||||||
if err := ParsePath(r, v); err != nil {
|
if err := ParsePath(r, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -54,6 +57,7 @@ func Parse(r *http.Request, v any) error {
|
|||||||
if err := ParseHeaders(r, v); err != nil {
|
if err := ParseHeaders(r, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := ParseJsonBody(r, v); err != nil {
|
if err := ParseJsonBody(r, v); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -325,11 +325,31 @@ func TestParseJsonBody(t *testing.T) {
|
|||||||
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body))
|
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body))
|
||||||
r.Header.Set(ContentType, header.JsonContentType)
|
r.Header.Set(ContentType, header.JsonContentType)
|
||||||
|
|
||||||
assert.NoError(t, ParseJsonBody(r, &v))
|
assert.NoError(t, Parse(r, &v))
|
||||||
assert.Equal(t, 1, len(v))
|
assert.Equal(t, 1, len(v))
|
||||||
assert.Equal(t, "kevin", v[0].Name)
|
assert.Equal(t, "kevin", v[0].Name)
|
||||||
assert.Equal(t, 18, v[0].Age)
|
assert.Equal(t, 18, v[0].Age)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("form and array body", func(t *testing.T) {
|
||||||
|
var v []struct {
|
||||||
|
// we can only ignore the form tag,
|
||||||
|
// because if the value is a slice, it should be in the body,
|
||||||
|
// but it's hard to detect when we treat it as a json body.
|
||||||
|
Product string `form:"product"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
}
|
||||||
|
|
||||||
|
body := `[{"name":"apple", "age": 18}]`
|
||||||
|
r := httptest.NewRequest(http.MethodPost, "/a?product=tree", strings.NewReader(body))
|
||||||
|
r.Header.Set(ContentType, header.JsonContentType)
|
||||||
|
|
||||||
|
assert.NoError(t, Parse(r, &v))
|
||||||
|
assert.Equal(t, 1, len(v))
|
||||||
|
assert.Equal(t, "apple", v[0].Name)
|
||||||
|
assert.Equal(t, 18, v[0].Age)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseRequired(t *testing.T) {
|
func TestParseRequired(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user