分享
  1. 首页
  2. 文章

golang通过反射使用json字符串调用struct的指定方法及返回json结果

changjixiong · · 2124 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

起因

在很多场合会存在这样一个需求或者想法:提交一个类似这样的json

{
 "func_name":"FooBarAdd",
 "params":[
 123.4,
 432.1
 ]
}

然后得到一个这样的json

{
 "func_name":"FooBarAdd",
 "data":[
 555.5
 ]
}

要达到这样的目的,必须要先解析提交的json, 获取到方法名和参数,然后找到拥有这个方法的实体,将参数做适当的类型转换后调用方法,最后将得到的结果包装成json返回。
至于这个json是通过http提交与返回,还是通过websocket提交与返回,抑或是通过tcp直接提交与返回,都是可以的。下面来看一下如何达到这个目的。

通过反射获取struct指定的方法

假设现在有一个struct是这样的

type FooBar struct {
}
func (f *FooBar) FooBarAdd(argOne, argTwo float64) float64 {
 return argOne + argTwo
}

对于BarFuncAdd方法,可以这样调用:

foobar := &FooBar{}
resultCallByName :=reflect.ValueOf(foobar).MethodByName("FooBarAdd").
 Call([]reflect.Value{reflect.ValueOf(123.4),reflect.ValueOf(432.1)})
fmt.Println(resultCallByName[0].Float())

也可以这样调用:

foobar := &FooBar{}
resultCallByIndex :=reflect.ValueOf(foobar).Method(0).
 Call([]reflect.Value{reflect.ValueOf(123.4),reflect.ValueOf(432.1)})
fmt.Println(resultCallByIndex[0].Float())

结果都是555.5

通过json字符串调用

如果想用一串这样的json

{
 "func_name":"FooBarAdd",
 "params":[
 123.4,
 432.1
 ]
}

得到一个这样的结果

{
 "func_name":"FooBarAdd",
 "data":[
 555.5
 ]
}

则可以这样调用

foobar := &FooBar{}
jsonData := `
 {
 "func_name":"FooBarAdd",
 "params":[
 123.4,
 432.1
 ]
 }
`
type RequestInfo struct {
 FuncName string `json:"func_name"`
 Params []interface{} `json:"params"`
}
type ResultInfo struct {
 FuncName string `json:"func_name"`
 Data []interface{} `json:"data"`
}
requestInfo := &RequestInfo{}
json.Unmarshal([]byte(jsonData), &requestInfo)
resultCallByJson :=reflect.ValueOf(foobar).MethodByName(requestInfo.FuncName).
 Call([]reflect.Value{reflect.ValueOf(requestInfo.Params[0]),
 reflect.ValueOf(requestInfo.Params[1])})
result := &ResultInfo{FuncName:requestInfo.FuncName,
 Data: []interface{{resultCallByJson[0].Interface()}}
jsonResult, _ := json.Marshal(&result)
fmt.Printf("%s\n", jsonResult)

适当的完善

是不是觉得还少了点什么,比如要是参数个数不匹配怎么办?类型转化怎么处理?如何做到更通用比如像这样调用:

jsonDataBarFuncSwap := `
{
 "func_name":"BarSwap",
 "params":[
 0.1,
 0.9
 ]
}
`
result:=string(reflectinvoke.InvokeByJson([]byte(jsonStr))

完整的代码范例,请看github上面的代码


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2124 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏