在Scala 2.10中,显然我们的反思得到了改善。
这将如何影响升,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
没有箍跳(即样板准备工作),即使是任意复杂的物体图。也许我问得太多了,但总能做到梦想。请打破我的2.10梦想,或者通过备受期待的Scala版本开启新的途径。接下来
此外,关于案例类,似乎验证/创建,scalaz验证是首选的武器。它看起来非常精彩,可以作为对象创建的安全代理或作为错误收集器。然而,作为一个Scewbie,我发现scalaz有点挑战性,并且尽管它具有明显的力量,我仍然抵抗F-ing黑暗面; - )
无论如何,这里的重点是,2.10反射我们应该能够在运行时将字段从表格帖子绑定到案例类的属性,并仅基于属性类型执行基本验证(即将不必指定单独的验证逻辑,指定属性foo必须是一个String,因为它的类型已经在我们现在可以正确反映的case类中定义了)
那么,勇敢的新世界到来了,还是现有的工具是可预见的未来的支柱?
答案 0 :(得分: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:
apply
和unapply
的类型构建复杂的宏方法)。在一天结束时,我们可以使用此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)
一点注意事项:新的API甚至足够聪明,能够验证"读取"累积错误......
来自@mandubian的一系列博客我会从这里推荐,因为它们非常具有启发性!
令人遗憾的是,Play 2的模块化......并不能让我们单独使用这个API!因此,它应该从整个游戏库中使用:/ 这可能在未来发生变化......
现在,未来越来越近了,因为Pascal有这个repo使我们能够使用play-json API。
因此,可以使用此回购直到Play 2.2将被释放。实际上,这个版本将与json或iteratees等几个API完全解耦,因此,我们可以直接使用playframework repo。
答案 1 :(得分:4)
Jerkson今天处理您的用例!
Json.generate(foo)
它还支持我们在生产中广泛使用的流式读写。
Json.generate(foo, outputStream)
Json.parse[Foo](inputStream)
我们最初使用的是lift-json,但它缺乏对案例类的流式支持,因此无法读取和编写大型json文档。 Jerkson也非常快,完美地处理嵌套的案例类。
答案 2 :(得分:0)
发表关于此事的博客文章,请在http://pedrorijo.com/blog/scala-json/
查看使用案例类和Play WS(已包含在Play框架中),您可以在json和case类之间进行转换,并使用简单的单行隐式
case class User(username: String, friends: Int, enemies: Int, isAlive: Boolean)
object User {
implicit val userJsonFormat = Json.format[User]
}