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,12 +70,14 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
 | 
			
		||||
		return isSetted, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ok, err := tryToSetValue(value, field, setter, tag)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, err
 | 
			
		||||
	}
 | 
			
		||||
	if ok {
 | 
			
		||||
		return true, nil
 | 
			
		||||
	if vKind != reflect.Struct || !field.Anonymous {
 | 
			
		||||
		ok, err := tryToSetValue(value, field, setter, tag)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
		if ok {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if vKind == reflect.Struct {
 | 
			
		||||
@ -83,7 +85,8 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
 | 
			
		||||
 | 
			
		||||
		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