[英]Creating a Json array in Scala
我正在尝试像这样创建一个 Json 对象
{ "Field1": [{}, {}, {}, {}], "Field2": [{}, {}, {}], "Field3": {} }
通常在 Java 中,我可以通过(特别是使用 google simple json)来实现这一点
以上结果来自不同的进程,我需要返回一个组合的 json 对象
我很困惑如何在 Scala 中实现相同的目标,我尝试了多种库和方法。 我正在尝试的最新版本是 json4s。 我以为我可以
我认为这会像在 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.