mirror of
https://gitee.com/johng/gf
synced 2026-07-07 06:15:15 +08:00
fix issue #1488
This commit is contained in:
@ -16,6 +16,16 @@ func (r *Request) SetParam(key string, value interface{}) {
|
||||
r.paramsMap[key] = value
|
||||
}
|
||||
|
||||
// SetParamMap sets custom parameter with key-value pair map.
|
||||
func (r *Request) SetParamMap(data map[string]interface{}) {
|
||||
if r.paramsMap == nil {
|
||||
r.paramsMap = make(map[string]interface{})
|
||||
}
|
||||
for k, v := range data {
|
||||
r.paramsMap[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// GetParam returns custom parameter with given name `key`.
|
||||
// It returns `def` if `key` does not exist.
|
||||
// It returns nil if `def` is not passed.
|
||||
|
||||
@ -527,3 +527,50 @@ func Test_Params_Struct_Validation(t *testing.T) {
|
||||
t.Assert(c.PostContent(ctx, "/", `id=1`), `The name field is required`)
|
||||
})
|
||||
}
|
||||
|
||||
// https://github.com/gogf/gf/issues/1488
|
||||
func Test_Params_Parse_Issue1488(t *testing.T) {
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||
group.ALL("/", func(r *ghttp.Request) {
|
||||
type Request struct {
|
||||
Type []int `p:"type"`
|
||||
Keyword string `p:"keyword"`
|
||||
Limit int `p:"per_page" d:"10"`
|
||||
Page int `p:"page" d:"1"`
|
||||
Order string
|
||||
CreatedAtLte string
|
||||
CreatedAtGte string
|
||||
CreatorID []int
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
r.SetParamMap(g.Map{
|
||||
"type[]": 0,
|
||||
"keyword": "",
|
||||
"t_start": "",
|
||||
"t_end": "",
|
||||
"reserve_at_start": "",
|
||||
"reserve_at_end": "",
|
||||
"user_name": "",
|
||||
"flag": "",
|
||||
"per_page": 6,
|
||||
})
|
||||
var parsed Request
|
||||
_ = r.Parse(&parsed)
|
||||
r.Response.Write(parsed.Page, parsed.Limit)
|
||||
}
|
||||
})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
c := g.Client()
|
||||
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p))
|
||||
t.Assert(c.GetContent(ctx, "/", ``), `16161616161616161616`)
|
||||
})
|
||||
}
|
||||
|
||||
@ -18,9 +18,15 @@ type Type struct {
|
||||
|
||||
// Field contains information of a struct field .
|
||||
type Field struct {
|
||||
Value reflect.Value // The underlying value of the field.
|
||||
Field reflect.StructField // The underlying field of the field.
|
||||
TagValue string // Retrieved tag value. There might be more than one tags in the field, but only one can be retrieved according to calling function rules.
|
||||
Value reflect.Value // The underlying value of the field.
|
||||
Field reflect.StructField // The underlying field of the field.
|
||||
|
||||
// Retrieved tag name. It depends TagValue.
|
||||
TagName string
|
||||
|
||||
// Retrieved tag value.
|
||||
// There might be more than one tags in the field, but only one can be retrieved according to calling function rules.
|
||||
TagValue string
|
||||
}
|
||||
|
||||
// FieldsInput is the input parameter struct type for function Fields.
|
||||
|
||||
@ -180,7 +180,8 @@ func getFieldValuesByTagPriority(pointer interface{}, priority []string, tagMap
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
tagValue = ""
|
||||
tagName string
|
||||
tagValue string
|
||||
tagFields = make([]Field, 0)
|
||||
)
|
||||
for _, field := range fields {
|
||||
@ -190,6 +191,7 @@ func getFieldValuesByTagPriority(pointer interface{}, priority []string, tagMap
|
||||
}
|
||||
tagValue = ""
|
||||
for _, p := range priority {
|
||||
tagName = p
|
||||
tagValue = field.Tag(p)
|
||||
if tagValue != "" && tagValue != "-" {
|
||||
break
|
||||
@ -201,6 +203,7 @@ func getFieldValuesByTagPriority(pointer interface{}, priority []string, tagMap
|
||||
continue
|
||||
}
|
||||
tagField := field
|
||||
tagField.TagName = tagName
|
||||
tagField.TagValue = tagValue
|
||||
tagFields = append(tagFields, tagField)
|
||||
}
|
||||
|
||||
@ -34,8 +34,8 @@ var (
|
||||
}
|
||||
|
||||
// StructTagPriority defines the default priority tags for Map*/Struct* functions.
|
||||
// Note, the "gconv", "param", "params" tags are used by old version of package.
|
||||
// It is strongly recommended using short tag "c" or "p" instead in the future.
|
||||
// Note, the `gconv/param/params` tags are used by old version of package.
|
||||
// It is strongly recommended using short tag `c/p` instead in the future.
|
||||
StructTagPriority = []string{"gconv", "param", "params", "c", "p", "json"}
|
||||
)
|
||||
|
||||
|
||||
@ -248,6 +248,12 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string
|
||||
// orm:"id, priority"
|
||||
// orm:"name, with:uid=id"
|
||||
tagMap[attributeName] = utils.RemoveSymbols(strings.Split(tagName, ",")[0])
|
||||
|
||||
// If tag and attribute values both exist in `paramsMap`,
|
||||
// it then uses the tag value overwriting the attribute value in `paramsMap`.
|
||||
if paramsMap[tagName] != nil && paramsMap[attributeName] != nil {
|
||||
paramsMap[attributeName] = paramsMap[tagName]
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
@ -269,7 +275,7 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string
|
||||
// string cases and chars like '-'/'_'/'.'/' '.
|
||||
|
||||
// Matching the parameters to struct tag names.
|
||||
// The `tagV` is the attribute name of the struct.
|
||||
// The `attrKey` is the attribute name of the struct.
|
||||
for attrKey, cmpKey := range tagMap {
|
||||
if strings.EqualFold(checkName, cmpKey) {
|
||||
attrName = attrKey
|
||||
@ -297,12 +303,12 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string
|
||||
continue
|
||||
}
|
||||
// If the attribute name is already checked converting, then skip it.
|
||||
if _, ok := doneMap[attrName]; ok {
|
||||
if _, ok = doneMap[attrName]; ok {
|
||||
continue
|
||||
}
|
||||
// Mark it done.
|
||||
doneMap[attrName] = struct{}{}
|
||||
if err := bindVarToStructAttr(pointerElemReflectValue, attrName, mapV, mapping); err != nil {
|
||||
if err = bindVarToStructAttr(pointerElemReflectValue, attrName, mapV, mapping); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user