簡體   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