Scala 2.10,它对JSON库和案例类验证/创建的影响

vir*_*yes 25 reflection json scala instantiation coercion

在Scala 2.10中,显然我们正在改进反思.

这将如何影响lift-json,jerkson,sjson和朋友?此外,我们能否在不久的将来期望内置的JSON语言功能和Scala中的Groovy优秀GSON?

我问的原因是我非常喜欢这样做:

case class Foo(a: String, b: Int, bar: Bar)
case class Bar(c: Int)
val foo = Foo("hey", 10, Bar(23))
val json = foo.toJson
Run Code Online (Sandbox Code Playgroud)

没有环跳(即样板准备工作),即使是任意复杂的对象图.也许我问得太多了,但总能做到梦想.请打破我的2.10梦想,或者通过备受期待的Scala版本打开新的途径.

此外,关于案例类,似乎验证/创建,scalaz验证是首选的武器.它看起来非常精彩,可以作为对象创建的安全代理或作为错误收集器.然而,作为一个Scewbie,我发现scalaz有点挑战性,并且尽管它有明显的力量,我仍然抵抗F-ing黑暗面;-)

无论如何,这里的重点是,2.10反射我们应该能够在运行时绑定从表单帖子到案例类的属性的字段,并仅基于属性类型执行基本验证(即不会指定单独的验证逻辑,指定属性foo必须是一个String,因为它的类型已在case类中定义,我们现在可以正确地反映它

那么,勇敢的新世界到来,还是现有的工具是可预见的未来的支柱?

and*_*lla 6

前言

让我给出一个不依赖于任何基于Java的库但只依赖于纯Scala库的不同解决方案.

实际上,正如@ Steve的结果中所讨论的那样,Play 2的scala版本正在使用Jerkson将Json序列化为域模型.Jerkson是一个用于处理Json的非常好的Java库的DSL包装器.

回答

上面没有回答你的问题,因为你问是否已经设想使用Scala 2.10的反射和宏功能来缓解这个任务!通过消除大多数锅炉板.

事实上,这是一个非常好的想法,因为从Play 2.1版本开始,Json Scala API不再使用Jerkson,而是它自己的机制.

事实上,这种机制通过引入基于两件事的全新API来利用这个新的2.10版Scala:

  • 功能构造(Applicative Builder),适用于读写Json或Domain实例.这些构建器用于粘合组合器(用于读取或写入),以便定义粗粒度结构(就像我们使用Parser Combinators一样)
  • 一堆宏能够发现哪些组合器是隐式可用的,并且将为Case Classes构建复杂的组(或者至少是具有applyunapply方法的类型).

在一天结束时,我们可以使用此API执行以下操作:

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class Person(name: String, age: Int, lovesChocolate: Boolean)

implicit val personReads = Json.format[Person] //a format is a Reader and a Writer

//this format will be implicitly used by the following from/toJson functions
val person:JsResult[Person] = Json.fromJson(json) //JsResult is like JsSucces/JsError
val jsObject = Json.toJson(person)
Run Code Online (Sandbox Code Playgroud)

代码复制和改编自:JSON Inception(基于Scala 2.10宏)

一点点说明:新的API甚至足够智能,能够通过累积错误来验证"读取"...

参考

@mandubian有一系列博客,我从这里推荐,因为它们非常具有启发性!

最后的说明

令人遗憾的是,Play 2的模块化......不允许我们单独使用这个API!因此,它应该从整个游戏库中使用:/这可能在未来发生变化......

编辑

现在,未来越来越近了,因为Pascal有这个回购使我们能够使用play-json API.

因此,可以使用此回购直到Play 2.2将被释放.实际上,这个版本将与json或iteratees等几个API完全解耦,因此,我们将能够直接使用playframework repo.


小智 4

Jerkson今天处理您的用例!

Json.generate(foo)
Run Code Online (Sandbox Code Playgroud)

它还支持我们在生产中广泛使用的流式读取和写入。

Json.generate(foo, outputStream)
Json.parse[Foo](inputStream)
Run Code Online (Sandbox Code Playgroud)

我们最初使用 lift-json,但它缺乏对案例类的流支持,导致它无法用于读取和写入大型 json 文档。Jerkson 的速度也非常快,可以完美地处理嵌套案例类。

  • 我必须再看一遍,上次我检查了 Jerkson 的创建者 Coda Hale,他或多或少地放弃了该项目(也请参阅 Yammer 从 Scala 中退出)。因此,理想的选择是提供开箱即用的 JSON 实用程序的内置语言功能,而不是依赖可能维护或不维护的外部库。 (3认同)
  • @Steve,看来 Play 不再使用 Jerkson。他们直接在 Jackson 上构建界面。来源:[Play Github 项目](https://github.com/playframework/Play20/tree/master/framework/src/play/src/main/scala/play/api/libs/json)。 (2认同)