繁体   English   中英

在 Scala 中创建一个 Json 数组

[英]Creating a Json array in Scala

我正在尝试像这样创建一个 Json 对象

 { "Field1": [{}, {}, {}, {}], "Field2": [{}, {}, {}], "Field3": {} }

通常在 Java 中,我可以通过(特别是使用 google simple json)来实现这一点

  1. 为 field1 和 field2 创建 JSON 数组,
  2. 为 Field3 创建 JSON 对象
  3. 将上面的3个组合成另一个JSONObject

以上结果来自不同的进程,我需要返回一个组合的 json 对象

我很困惑如何在 Scala 中实现相同的目标,我尝试了多种库和方法。 我正在尝试的最新版本是 json4s。 我以为我可以

  1. 遍历字符串列表并将它们放入“json 数组”中
  2. 使用键将上述数组添加到另一个“json 对象”中
  3. 返回组合的 json 对象

我认为这会像在 Java 中一样简单,我是否遗漏了一些明显的东西? (我是 Scala 新手)。

任何帮助将非常感激。

我将scala 模块与 jackson 、 JsonUtil.scala 一起使用:

package json

import com.fasterxml.jackson.databind.{SerializationFeature, DeserializationFeature, ObjectMapper, PropertyNamingStrategy}
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

object JsonUtil {
  private val ObjectMapper = buildMapper()

  private def buildMapper() = {
    val mapper = new ObjectMapper() with ScalaObjectMapper
    mapper.registerModule(DefaultScalaModule)
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    mapper.enable(SerializationFeature.INDENT_OUTPUT)
    mapper
  }

  def fromJson[A](json: String, objectType: Class[A]): A = {
    ObjectMapper.readValue(json, objectType)
  }

  def toJson(data: AnyRef): String = {
    ObjectMapper.writeValueAsString(data)
  }
}

依赖项:

compile 'com.fasterxml.jackson.core:jackson-core:2.6.3'
compile 'com.fasterxml.jackson.module:jackson-module-scala_2.11:2.6.3'

然后,它很容易使用:

case class MyDto(id: Int, name: Option[String])
...
val jsonString = JsonUtil.toJson(MyDto(123, Some("John Doe")))
val dto = JsonUtil.fromJson(jsonString, classOf[MyDto])

case class MyList(items: List[Int])
...
val jsonList = JsonUtil.toJson(MyList(List(1,2,3,4,5)))

这是在circe 中执行此操作的一种方法:

import io.circe.syntax._

val json = Map(
  "Field1" -> List.fill(4)(()).asJson,
  "Field2" -> List.fill(3)(()).asJson,
  "Field3" -> ().asJson
).asJson

进而:

scala> json.noSpaces
res0: String = {"Field1":[{},{},{},{}],"Field2":[{},{},{}],"Field3":{}}

这里有几点需要注意。 第一个是 Scala 鼓励使用不可变集合,因此不是“将值放入”列表,而是使用List.fill(n)(value)类的实用程序,它创建一个重复n次的value列表。 这意味着List.fill(3)(())List((), (), ())完全相同,我们也可以在上面使用。

第二点是更特定于 circe 的。 ()是 Scala 中的一个特殊值——它是Unit类型的唯一值,它只代表一个不携带任何信息的空东西。 实际上()的 JSON 编码是{} ,因此我们可以通过调用().asJson来创建一个空的 JSON 对象。

circe 还知道如何从它知道如何编码的任何类型的 Scala 列表(或其他序列)中创建一个 JSON 数组,所以List.fill(3)(()).asJson是一个 JSON 值,它是一个 JSON 数组三个空的 JSON 对象。

最后,circe 还知道如何从 Scala Map创建一个 JSON 对象,其中键是字符串,值类型是它知道如何编码的东西。 这意味着我们可以创建一个Map[String, io.circe.Json]类型的Map[String, io.circe.Json]并在其上调用asJson以获取一个 JSON 值,该值是一个包含由映射表示的字段的 JSON 对象。

根据您的具体用例,还有其他方法可以在 circe 中执行此操作,这些方法可能会更好,包括以下内容:

case class Fields(Field1: List[Unit], Field2: List[Unit], Field3: Unit)

进而:

scala> import io.circe.generic.auto._
import io.circe.generic.auto._

scala> Fields(List((), (), (), ()), List((), (), ()), ()).asJson.noSpaces
res0: String = {"Field1":[{},{},{},{}],"Field2":[{},{},{}],"Field3":{}}

这种方法(使用 circe 对通用编解码器派生的支持)通常比直接使用 JSON 值更惯用。

虽然有点冗长,但您可以使用播放框架 这允许编写案例类对象,然后直接将它们转换为 JSON 对象。 以下示例有点松散,因为您没有说明对象的确切外观。

case class ResponseObject(a: Field1, b: Field2, c: Field3)
case class Field1(a: Seq[Field1obj])
case class Field2(a: Seq[Field2obj]))
case class Field3(a: Field3obj)
case class Field1obj(a: String, b: Int)
...

然后你可以使用

implicit val responseWrites = Json.writes[ResponseObject]
implicit val fieldWrites = Json.writes[Field1]
...
val resultToSend = ResponseObject(field1, field2, field3)
val json = Json.toJson(resultToSend)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM