在Scala中将JSON以一种格式转换为另一种格式

时间:2015-05-19 20:23:53

标签: json scala converter

我正在寻找可以帮助我在Scala中将JSON(带嵌套结构)从一种格式转换为另一种格式的建议或库。

我看到有一些基于JavaScript和Java的解决方案。 Scala中的任何东西?

2 个答案:

答案 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)

}