ghttp增加输入参数与struct的绑定机制,并增加对应params标签支持

This commit is contained in:
John
2018-08-12 10:50:03 +08:00
parent 94192fbceb
commit 67855a5b79
10 changed files with 111 additions and 16 deletions

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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}
}