Now you can parse the inline lowercase start structure (#1893)
* Now you can parse the inline lowercase start structure
package main
import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
)
type appkey struct {
	Appkey string `json:"appkey" form:"appkey"`
}
type Query struct {
	Page int `json:"page" form:"page"`
	Size int `json:"size" form:"size"`
	appkey
}
func main() {
	router := gin.Default()
	router.POST("/login", func(c *gin.Context) {
		var q2 Query
		if c.ShouldBindQuery(&q2) == nil {
			c.JSON(200, &q2)
		}
	})
	router.Run(":8088")
}
http client:
old:
curl -X POST "127.0.0.1:8088/login?appkey=china&page=1&size=10"
{"page":1,"size":10,"appkey":""}
now:
curl -X POST "127.0.0.1:8088/login?appkey=china&page=1&size=10"
{"page":1,"size":10,"appkey":"china"}
* Modify judgment conditions
			
			
This commit is contained in:
		| @ -24,6 +24,16 @@ import ( | ||||
| 	"github.com/ugorji/go/codec" | ||||
| ) | ||||
|  | ||||
| type appkey struct { | ||||
| 	Appkey string `json:"appkey" form:"appkey"` | ||||
| } | ||||
|  | ||||
| type QueryTest struct { | ||||
| 	Page int `json:"page" form:"page"` | ||||
| 	Size int `json:"size" form:"size"` | ||||
| 	appkey | ||||
| } | ||||
|  | ||||
| type FooStruct struct { | ||||
| 	Foo string `msgpack:"foo" json:"foo" form:"foo" xml:"foo" binding:"required"` | ||||
| } | ||||
| @ -189,6 +199,18 @@ func TestBindingForm2(t *testing.T) { | ||||
| 		"", "") | ||||
| } | ||||
|  | ||||
| func TestBindingFormEmbeddedStruct(t *testing.T) { | ||||
| 	testFormBindingEmbeddedStruct(t, "POST", | ||||
| 		"/", "/", | ||||
| 		"page=1&size=2&appkey=test-appkey", "bar2=foo") | ||||
| } | ||||
|  | ||||
| func TestBindingFormEmbeddedStruct2(t *testing.T) { | ||||
| 	testFormBindingEmbeddedStruct(t, "GET", | ||||
| 		"/?page=1&size=2&appkey=test-appkey", "/?bar2=foo", | ||||
| 		"", "") | ||||
| } | ||||
|  | ||||
| func TestBindingFormDefaultValue(t *testing.T) { | ||||
| 	testFormBindingDefaultValue(t, "POST", | ||||
| 		"/", "/", | ||||
| @ -688,6 +710,23 @@ func TestUriInnerBinding(t *testing.T) { | ||||
| 	assert.Equal(t, tag.S.Age, expectedAge) | ||||
| } | ||||
|  | ||||
| func testFormBindingEmbeddedStruct(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, "form", b.Name()) | ||||
|  | ||||
| 	obj := QueryTest{} | ||||
| 	req := requestWithBody(method, path, body) | ||||
| 	if method == "POST" { | ||||
| 		req.Header.Add("Content-Type", MIMEPOSTForm) | ||||
| 	} | ||||
| 	err := b.Bind(req, &obj) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, 1, obj.Page) | ||||
| 	assert.Equal(t, 2, obj.Size) | ||||
| 	assert.Equal(t, "test-appkey", obj.Appkey) | ||||
|  | ||||
| } | ||||
|  | ||||
| func testFormBinding(t *testing.T, method, path, badPath, body, badBody string) { | ||||
| 	b := Form | ||||
| 	assert.Equal(t, "form", b.Name()) | ||||
|  | ||||
| @ -70,6 +70,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag | ||||
| 		return isSetted, nil | ||||
| 	} | ||||
|  | ||||
| 	if vKind != reflect.Struct || !field.Anonymous { | ||||
| 		ok, err := tryToSetValue(value, field, setter, tag) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| @ -77,13 +78,15 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag | ||||
| 		if ok { | ||||
| 			return true, nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if vKind == reflect.Struct { | ||||
| 		tValue := value.Type() | ||||
|  | ||||
| 		var isSetted bool | ||||
| 		for i := 0; i < value.NumField(); i++ { | ||||
| 			if !value.Field(i).CanSet() { | ||||
| 			sf := tValue.Field(i) | ||||
| 			if sf.PkgPath != "" && !sf.Anonymous { // unexported | ||||
| 				continue | ||||
| 			} | ||||
| 			ok, err := mapping(value.Field(i), tValue.Field(i), setter, tag) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user