我正在寻找可以帮助我在Scala中将JSON(带嵌套结构)从一种格式转换为另一种格式的建议或库。
我看到有一些基于JavaScript和Java的解决方案。 Scala中的任何东西?
答案 0 :(得分:6)
我非常喜欢Play JSON库。它的API非常干净,即使某些部分的学习曲线略微陡峭,它也非常快。即使您没有使用Play的其余部分,也可以使用Play JSON库。
https://playframework.com/documentation/2.3.x/ScalaJson
要将JSON转换为scala对象(反之亦然),Play会使用含义。有Reads
类型指定如何将JSON转换为scala类型,Writes
类型指定如何将scala对象转换为JSON。
例如:
case class Foo(a: Int, b: String)
您可以采用一些不同的路线将Foo
转换为JSON。如果您的对象很简单(例如Foo
),Play JSON可以为您创建转换函数:
implicit val fooReads = Json.reads[Foo]
或者如果您想要更多控制或类型更复杂,您可以创建自定义转换功能。以下示例对id
中的属性a
使用名称Foo
:
implicit val fooReads = (
(__ \ "id").read[Int] ~
(__ \ "name").read[String]
)(Foo)
Writes
类型具有类似功能:
implicit val fooWrites = Json.writes[Foo]
或
implicit val fooWrites = (
(JsPath \ "id").write[Int] and
(JsPath \ "name").write[String]
)(unlift(Foo.unapply))
您可以在此处详细了解Reads
/ Writes
(以及您需要的所有导入):https://playframework.com/documentation/2.3.x/ScalaJsonCombinators
您也可以转换JSON,而无需将JSON映射到scala类型。这很快并且通常需要较少的样板。一个简单的例子:
import play.api.libs.json._
// Only take a single branch from the input json
// This transformer takes the entire JSON subtree pointed to by
// key bar (no matter what it is)
val pickFoo = (__ \ 'foo).json.pickBranch
// Parse JSON from a string and apply the transformer
val input = """{"foo": {"id": 10, "name": "x"}, "foobar": 100}"""
val baz: JsValue = Json.parse(input)
val foo: JsValue = baz.transform(pickFoo)
您可以在此处阅读有关直接转换JSON的更多信息:https://playframework.com/documentation/2.3.x/ScalaJsonTransformers
答案 1 :(得分:1)
您可以使用Json4s Jackson
。使用PlayJson,您必须为所有案例类编写隐式转换。如果没有。类很小,开发时不会频繁更改,PlayJson似乎还可以。但是,如果案例类更多,我建议使用json4s。
您需要为不同类型添加隐式转换,以便json4s在转换为json时能够理解。
您可以将以下依赖项添加到项目中以获取json4s-jackson
"org.json4s" %% "json4s-jackson" % "3.2.11"
下面给出了一个示例代码(序列化和反序列化):
import java.util.Date
import java.text.SimpleDateFormat
import org.json4s.DefaultFormats
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.{Serialization}
/**
* Created by krishna on 19/5/15.
*/
case class Parent(id:Long, name:String, children:List[Child])
case class Child(id:Long, name:String, simple: Simple)
case class Simple(id:Long, name:String, date:Date)
object MainClass extends App {
implicit val formats = (new DefaultFormats {
override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd")
}.preservingEmptyValues)
val d = new Date()
val simple = Simple(1L, "Simple", d)
val child1 = Child(1L, "Child1", simple)
val child2 = Child(2L, "Child2", simple)
val parent = Parent(1L, "Parent", List(child1, child2))
//Conversion from Case Class to Json
val json = Serialization.write(parent)
println(json)
//Conversion from Json to Case Class
val parentFromJson = parse(json).extract[Parent]
println(parentFromJson)
}