0

我正在 Play 2.1 中构建一个 JSON RPC。为了调用正确的方法,RPC 调度程序使用反射来创建并按名称调用类方法实例。

现在一个 RPC 方法看起来像这样:

  def create(obj: JsValue) = {
    val menu: Menu = Json.fromJson[Menu](obj).get
    collection.insert(menu).map( r => toDirectResult(r))
  }

  def createCustom(obj: JsValue) = {
    val menu: Menu = Json.fromJson(obj)(Menu.customFormat).get
    collection.insert(menu).map( r => toDirectResult(r))
  }

我想做的是能够像这样定义 RPC 方法:

  def create(menu: Menu) = {
    collection.insert(menu).map( r => toDirectResult(r))
  }

问题是 RPC 调度程序仅在运行时知道必须在名为“Menus”的类上调用名为“create”的方法,并且它具有作为 JsValue 传递给该方法的参数值。通过反射,我可以找出 RPC 方法的参数数量及其类型。当参数类型是案例类时,如何使用案例类的伴随对象中定义的隐式Formatter(或Reader)将JsValue转换为案例类实例?

对于 createCustom 方法,我意识到没有“神奇”的解决方案,但自从我开始学习 Scala 后,我发现用这种编程语言几乎没有什么是真正不可能的。是否可以使用注释或类似的东西来指定非隐式的格式化程序?

4

2 回答 2

0

你需要实现一个 PathBinder ......这应该有助于http://www.richard-foy.fr/blog/2012/04/09/how-to-implement-a-custom-pathbindable-with-play-2 /

于 2013-07-07T21:00:46.343 回答
0

经过进一步仔细考虑后,我认为反射确实不是解决我问题的正确方法。它在编译时缺乏类型安全和适当的错误报告,更难调试并且对性能也有影响。而且我实际上拥有在构建时生成代码所需的所有信息。

不幸的是,我不能使用 Play 路由器,因为对于 JSON RPC 调度程序,路由取决于请求正文,而在 Play 路由期间不可用。但本质上,RPC 调度程序与 Play 路由器做同样的事情。所以目前我只是要手动编写我的 RPC 路由,然后问题中的问题就解决了。将来我打算编写一个 SBT 插件,它会自动生成调度程序代码,类似于 Play 路由器。

于 2013-07-17T01:52:07.390 回答