[英]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.