我想将路由器配置放入外部json配置文件中,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
 "routes": [
    {
     "name":"Index",
     "method":"GET",
     "pattern":"/",
     "handler":"Index"
    },
    {
     "name":"CountsIndex",
     "method":"GET",
     "pattern":"/counts",
     "handler":"CountsIndex"
    }
  ]
}

我的相关结构如下:

1
2
3
4
5
6
7
8
type Route struct {
    Name        string      `json:"name"`
    Method      string      `json:"method"`
    Pattern     string      `json:"pattern"`
    HandlerFunc http.HandlerFunc    `json:"handler"`
}

type Routes []Route

问题是处理程序功能。当我得到配置时,它将是一个字符串,但是如何使其成为go值?我可以以某种方式投射吗?

发生以下错误:

json: cannot unmarshal string into Go value of type http.HandlerFunc

谢谢

  • 您在这里需要小心:将其从源代码中删除意味着您有可能在代码中不存在JSON文件中的内容,因此您必须进行仔细测试(例如遍历route.Handler字段和打电话给每个人)。是否有理由需要将其保存在JSON文件中,而不是(例如)获得相同结果的routes.go?您的服务是否遇到需要添加路由而无需重新编译的情况?

最简单的解决方案是使用字符串而不是http.HandlerFunc作为类型,并使用函数定义映射。

1
2
3
var functions = map[string]interface{}{
   "func1": func1,
}

然后解组json后,您可以使用每个路由的处理程序名称分配处理程序

  • 我试过:var handlers = map [string] http.HandlerFunc {\\\\ t?? " index ":索引,\\\\ t " countsIndex ":CountsIndex,},但分配它时出现此错误:无法使用路由.HandlerFunc(类型http.HandlerFunc)作为地图索引中的类型字符串
  • 好的,我使处理程序在结构中成为字符串,然后它可以工作。但是现在我每次扩展配置hmm时都必须添加处理程序。
  • 不幸的是,您无法枚举包中声明的所有函数,这应该已经解决了每次将处理程序添加到映射时要添加的问题
  • 对此进行一些小的更改以使其对我有用:var functions = map [string] http.HandlerFunc

问题在于,并非所有数据都可以封送至json(或取消封送)。 http.HandlerFunc不是函数(https://golang.org/pkg/net/http/#HandlerFunc)。您不能直接放置它-但是可以在尝试调用它时将处理程序更改为字符串,并在该位置上从反射(相当复杂)或从准备好的map [string] HandlerFunc获得HandlerFunc。

  • 谢谢,但是你能举个例子吗?
  • 抱歉,我犯了一个错误-但是,我可以识别模块中的所有功能。这是不可能的-只有我能从对象或类型中找到方法和执行方法。这意味着仅当所有方法都是相同对象的方法时,才可以使用反射。