Scala:将JSON直接解析成case类

40

给定一个JSON字符串和对应的case class,将JSON解析成case class的简单方法是什么?有很多库可供选择,但似乎Scala现在可以直接处理。

如果要将JSON解析成case class列表怎么办?

更新:

Jerkson似乎已经被放弃了,我不想安装完整的Play或Lift框架或其他沉重的东西。


你不必安装完整的框架 - 你只需要将json库列为依赖项。我知道这适用于lift-json和spray-json,其他库可能也适用。 - AmigoNico
7个回答

24

有几个框架可以确切地做到这一点。

circe

现在被广泛使用,具有许多强大的功能。将拉入cats库。

https://circe.github.io/circe/ https://github.com/circe/circe

JSON4s

JSON4s非常成熟,支持jackson或本地JSON解析器。我在许多项目中使用它来替换jerkson。

https://github.com/json4s/json4s

play-json

可以在没有完整play堆栈的情况下使用。作为typesafe公司Play项目的一部分提供了很好的支持。

http://www.playframework.com/documentation/2.0/ScalaJson

Scala-Pickling

一个序列化框架。有一个选项可以进行JSON序列化和反序列化。

https://github.com/scala/pickling

Spray JSON

可以进行序列化和反序列化。但需要知道反序列化时参数的数量。

https://github.com/spray/spray-json


12

我使用了https://github.com/json4s/json4s,目前唯一的抱怨是https://github.com/json4s/json4s/issues/137

import org.json4s._
import org.json4s.native.JsonMethods._

implicit val formats = DefaultFormats

case class ParsedPage(crawlDate: String, domain:String, url:String, text: String)

val js = """ {
"crawlDate": "20150226",
"domain": "0x20.be",
"url": "http://0x20.be/smw/index.php?title=99_Bottles_of_Beer&oldid=6214",
"text": "99 Bottles of Beer From Whitespace (Hackerspace Gent) Revision as of 14:43, 8 August 2012 by Hans ( Talk | contribs ) 99 Bottles of Beer Where: Loading map... Just me, with 99 bottles of beer and some friends. Subpages"
}"""


parse(js).extract[ParsedPage]

1
此问题已得到解决。 - Robert Beltran
1
发现这是最好的“无需烦恼”的方法。虽然必须添加import org.json4s.jackson.JsonMethods._而不是....native才能使其工作。 - ChiMo

2

如果你是第一次遇到这个问题,circe也是一个不错的选择。

val customerJson = s"""{"id" : "1", "name" : "John Doe"}"""
case class Customer(id: String, name: String)
val customer = decode[Customer](customerJson)

2

使用spray-json,因为它很小。

import spray.json._
import DefaultJsonProtocol._


val json = """{"one" : "1", "two" : "2", "three" : "3"}""".parseJson

case class Numbers(one: String, two: String, three: String)

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit val numbersFormat = jsonFormat3(Numbers)

}

import MyJsonProtocol._

val converted = json.convertTo[Numbers]

使用以下build.sbt将spray-json下载到sbt中:

lazy val root = (project in file(".")). settings( name := "jsonExample", libraryDependencies += "io.spray" %% "spray-json" % "1.3.2" )

注意,保留HTML标记。

1
使用net.liftweb。
import net.liftweb.json._
case class Detail(username:String, password:String)
implicit val formats = DefaultFormats
val input = parse(jsonString).extract[Detail]
println(input.username)

确保Scala版本与lift-json jar匹配。例如,对于Scala 2.10,请使用lift-json_2.10。


0

0

Spray Json非常轻量级,而且正好满足您的需求。它是一个工具包而不是完整的框架,您可以只导入Spray-json项目而不是整个项目。

https://github.com/spray/spray-json

这些示例可以让您快速设置。大多数情况下,将代码转换为/从JSON的代码最终都是一行代码,但如果您有一些奇怪的要求,则可以明确处理它。


1
请注意,尽管 spray-json 在序列化方面非常快,但在反序列化方面速度极慢,无法使用。即使作者们承认它在反序列化方面不具有竞争力(除非进行额外的工作)。 - Andres F.
2
实际上,Spray-Json的反序列化性能在1.3.0中得到了很大的改善。https://groups.google.com/forum/#!msg/spray-user/oCKjHmUMDb0/pFZ5mJ0w9u4J - Onur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接