diff --git a/g/net/ghttp/ghttp_request.go b/g/net/ghttp/ghttp_request.go index 8f928ba21..3c727cda1 100644 --- a/g/net/ghttp/ghttp_request.go +++ b/g/net/ghttp/ghttp_request.go @@ -13,6 +13,8 @@ import ( "gitee.com/johng/gf/g/container/gtype" "gitee.com/johng/gf/g/util/gregex" "gitee.com/johng/gf/g/os/gtime" + "github.com/fatih/structs" + "strings" ) // 请求对象 @@ -93,6 +95,11 @@ func (r *Request) GetJson() *gjson.Json { return nil } +// 将所有的request参数映射到struct属性上,参数object应当为一个struct对象的指针, mapping为非必需参数,自定义参数与属性的映射关系 +func (r *Request) GetToStruct(object interface{}, mapping...map[string]string) { + r.GetRequestToStruct(object, mapping...) +} + // 退出当前请求执行,原理是在Request.exit做标记,由服务逻辑流程做判断,自行停止 func (r *Request) Exit() { r.exit.Set(true) @@ -133,3 +140,16 @@ func (r *Request) GetClientIp() string { return ip } +// 获得结构体顶替的参数名称标签,构成map返回 +func (r *Request) getStructParamsTagMap(object interface{}) map[string]string { + tagmap := make(map[string]string) + fields := structs.Fields(object) + for _, field := range fields { + if tag := field.Tag("params"); tag != "" { + for _, v := range strings.Split(tag, ",") { + tagmap[strings.TrimSpace(v)] = field.Name() + } + } + } + return tagmap +} \ No newline at end of file diff --git a/g/net/ghttp/ghttp_request_post.go b/g/net/ghttp/ghttp_request_post.go index 19acac344..263a6f952 100644 --- a/g/net/ghttp/ghttp_request_post.go +++ b/g/net/ghttp/ghttp_request_post.go @@ -93,3 +93,18 @@ func (r *Request) GetPostMap(defaultMap...map[string]string) map[string]string { } return m } + +// 将所有的request参数映射到struct属性上,参数object应当为一个struct对象的指针, mapping为非必需参数,自定义参数与属性的映射关系 +func (r *Request) GetPostToStruct(object interface{}, mapping...map[string]string) { + tagmap := r.getStructParamsTagMap(object) + if len(mapping) > 0 { + for k, v := range mapping[0] { + tagmap[k] = v + } + } + params := make(map[string]interface{}) + for k, v := range r.GetPostMap() { + params[k] = v + } + gconv.MapToStruct(params, object, tagmap) +} \ No newline at end of file diff --git a/g/net/ghttp/ghttp_request_query.go b/g/net/ghttp/ghttp_request_query.go index ca511be6e..aab97d10d 100644 --- a/g/net/ghttp/ghttp_request_query.go +++ b/g/net/ghttp/ghttp_request_query.go @@ -93,3 +93,17 @@ func (r *Request) GetQueryMap(defaultMap...map[string]string) map[string]string return m } +// 将所有的get参数映射到struct属性上,参数object应当为一个struct对象的指针, mapping为非必需参数,自定义参数与属性的映射关系 +func (r *Request) GetQueryToStruct(object interface{}, mapping...map[string]string) { + tagmap := r.getStructParamsTagMap(object) + if len(mapping) > 0 { + for k, v := range mapping[0] { + tagmap[k] = v + } + } + params := make(map[string]interface{}) + for k, v := range r.GetQueryMap() { + params[k] = v + } + gconv.MapToStruct(params, object, tagmap) +} \ No newline at end of file diff --git a/g/net/ghttp/ghttp_request_request.go b/g/net/ghttp/ghttp_request_request.go index 281cffde1..80289f1d1 100644 --- a/g/net/ghttp/ghttp_request_request.go +++ b/g/net/ghttp/ghttp_request_request.go @@ -77,3 +77,19 @@ func (r *Request) GetRequestMap(defaultMap...map[string]string) map[string]strin } return m } + +// 将所有的request参数映射到struct属性上,参数object应当为一个struct对象的指针, mapping为非必需参数,自定义参数与属性的映射关系 +func (r *Request) GetRequestToStruct(object interface{}, mapping...map[string]string) { + tagmap := r.getStructParamsTagMap(object) + if len(mapping) > 0 { + for k, v := range mapping[0] { + tagmap[k] = v + } + } + params := make(map[string]interface{}) + for k, v := range r.GetRequestMap() { + params[k] = v + } + gconv.MapToStruct(params, object, tagmap) +} + diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 45bb08b2a..0dbd8dd76 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -318,7 +318,7 @@ func MapToStruct(params map[string]interface{}, object interface{}, mapping...ma elem := reflect.ValueOf(object).Elem() dmap := make(map[string]bool) // 首先按照传递的映射关系进行匹配 - if len(mapping) > 0 { + if len(mapping) > 0 && len(mapping[0]) > 0 { for mappingk, mappingv := range mapping[0] { if v, ok := params[mappingk]; ok { dmap[mappingv] = true diff --git a/geg/frame/mvc/controller/demo/buildin_vars.go b/geg/frame/mvc/controller/demo/buildin_vars.go index 7870ea001..26358f26f 100644 --- a/geg/frame/mvc/controller/demo/buildin_vars.go +++ b/geg/frame/mvc/controller/demo/buildin_vars.go @@ -2,17 +2,15 @@ package demo import ( "gitee.com/johng/gf/g" - "gitee.com/johng/gf/g/frame/gmvc" + "gitee.com/johng/gf/g/net/ghttp" ) -type Order struct { - gmvc.Controller -} +type Order struct { } func init() { - g.Server().BindController("/{.struct}/{.method}", &Order{}) + g.Server().BindObject("/{.struct}-{.method}", new(Order)) } -func (o *Order) List() { - o.Response.Write("List") +func (o *Order) List(r *ghttp.Request) { + r.Response.Write("List") } diff --git a/geg/frame/mvc/controller/demo/object.go b/geg/frame/mvc/controller/demo/object.go index 73f714129..8c5f52aad 100644 --- a/geg/frame/mvc/controller/demo/object.go +++ b/geg/frame/mvc/controller/demo/object.go @@ -1,18 +1,21 @@ package demo -import "gitee.com/johng/gf/g/net/ghttp" +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/net/ghttp" +) type Object struct {} func init() { - ghttp.GetServer().BindObject("/object", &Object{}) + g.Server().BindObject("/object", new(Object)) } func (o *Object) Index(r *ghttp.Request) { - r.Response.Write("It's index!") + r.Response.Write("object index") } func (o *Object) Show(r *ghttp.Request) { - r.Response.Write("It's show time bibi!") + r.Response.Write("object show") } diff --git a/geg/frame/mvc/controller/demo/object_method.go b/geg/frame/mvc/controller/demo/object_method.go index 3123d6b7f..3922787b3 100644 --- a/geg/frame/mvc/controller/demo/object_method.go +++ b/geg/frame/mvc/controller/demo/object_method.go @@ -1,6 +1,7 @@ package demo import ( + "gitee.com/johng/gf/g" "gitee.com/johng/gf/g/net/ghttp" ) @@ -8,8 +9,8 @@ type ObjectMethod struct {} func init() { obj := &ObjectMethod{} - ghttp.GetServer().BindObjectMethod("/object-method", obj, "Show1, Show2, Show3") - ghttp.GetServer().Domain("localhost").BindObjectMethod("/object-method", obj, "Show4") + g.Server().BindObjectMethod("/object-method", obj, "Show1, Show2, Show3") + g.Server().Domain("localhost").BindObjectMethod("/object-method", obj, "Show4") } func (o *ObjectMethod) Show1(r *ghttp.Request) { diff --git a/geg/frame/mvc/controller/demo/product.go b/geg/frame/mvc/controller/demo/product.go index 45a317ea1..da3649dc6 100644 --- a/geg/frame/mvc/controller/demo/product.go +++ b/geg/frame/mvc/controller/demo/product.go @@ -3,7 +3,6 @@ package demo import ( "gitee.com/johng/gf/g" "gitee.com/johng/gf/g/net/ghttp" - "gitee.com/johng/gf/g/util/gconv" ) type Product struct { @@ -18,7 +17,7 @@ func init() { func (p *Product) Total(r *ghttp.Request) { p.total++ - r.Response.Write("total: ", gconv.String(p.total)) + r.Response.Write("total: ", p.total) } func (p *Product) List(r *ghttp.Request) { diff --git a/geg/net/ghttp/server/request/request_struct.go b/geg/net/ghttp/server/request/request_struct.go new file mode 100644 index 000000000..ad506b724 --- /dev/null +++ b/geg/net/ghttp/server/request/request_struct.go @@ -0,0 +1,29 @@ +package main + +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/net/ghttp" +) + +type User struct { + Uid int `json:"uid"` + Name string `json:"name" params:"username"` + Pass1 string `json:"pass1" params:"password1,userpass1"` + Pass2 string `json:"pass2" params:"password3,userpass2"` +} + +func main() { + s := g.Server() + s.BindHandler("/user", func(r *ghttp.Request){ + user := new(User) + r.GetToStruct(user) + //r.GetPostToStruct(user) + //r.GetQueryToStruct(user) + r.Response.WriteJson(user) + }) + s.SetPort(8199) + s.Run() + + // http://127.0.0.1:8199/user?uid=1&name=john&password1=123&userpass2=123 + // {"name":"john","pass1":"123","pass2":"123","uid":1} +} \ No newline at end of file