[英]Creating a Json array in Scala
I'm trying to create a Json object like so我正在尝试像这样创建一个 Json 对象
{ "Field1": [{}, {}, {}, {}], "Field2": [{}, {}, {}], "Field3": {} }
Typically in Java I could achieve this by (specifically using google simple json)通常在 Java 中,我可以通过(特别是使用 google simple json)来实现这一点
The results for the above are coming from separate processes, I need to return a combined json object以上结果来自不同的进程,我需要返回一个组合的 json 对象
I'm confused how to achieve the same in Scala, I tried multiple libraries and approaches.我很困惑如何在 Scala 中实现相同的目标,我尝试了多种库和方法。 The latest I'm trying is json4s.
我正在尝试的最新版本是 json4s。 I thought I could
我以为我可以
I thought this will be as straightforward as it is in Java, am I missing something obvious?我认为这会像在 Java 中一样简单,我是否遗漏了一些明显的东西? (I am Scala newbie).
(我是 Scala 新手)。
Any help would be much appreciated.任何帮助将非常感激。
I use scala module with jackson , JsonUtil.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)
}
}
Dependencies:依赖项:
compile 'com.fasterxml.jackson.core:jackson-core:2.6.3'
compile 'com.fasterxml.jackson.module:jackson-module-scala_2.11:2.6.3'
Then, it's easy to use:然后,它很容易使用:
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)))
Here's one way to do this in circe :这是在circe 中执行此操作的一种方法:
import io.circe.syntax._
val json = Map(
"Field1" -> List.fill(4)(()).asJson,
"Field2" -> List.fill(3)(()).asJson,
"Field3" -> ().asJson
).asJson
And then:进而:
scala> json.noSpaces
res0: String = {"Field1":[{},{},{},{}],"Field2":[{},{},{}],"Field3":{}}
There are a couple of things to note here.这里有几点需要注意。 The first is that Scala encourages the use of immutable collections, so instead of "putting values into" a list, you use utilities like
List.fill(n)(value)
, which creates a list of value
repeated n
times.第一个是 Scala 鼓励使用不可变集合,因此不是“将值放入”列表,而是使用
List.fill(n)(value)
类的实用程序,它创建一个重复n
次的value
列表。 This means List.fill(3)(())
is exactly the same as List((), (), ())
, which we could also have used above.这意味着
List.fill(3)(())
与List((), (), ())
完全相同,我们也可以在上面使用。
The second point is more circe-specific.第二点是更特定于 circe 的。
()
is a special value in Scala—it's the only value of type Unit
, which just represents an empty thing that carries no information. ()
是 Scala 中的一个特殊值——它是Unit
类型的唯一值,它只代表一个不携带任何信息的空东西。 In circe the JSON encoding of ()
is {}
, so we can create an empty JSON object by calling ().asJson
.实际上
()
的 JSON 编码是{}
,因此我们可以通过调用().asJson
来创建一个空的 JSON 对象。
circe also knows how to create a JSON array out of a Scala list (or other sequence) of any type that it knows how to encode, so List.fill(3)(()).asJson
is a JSON value that's a JSON array of three empty JSON objects. circe 还知道如何从它知道如何编码的任何类型的 Scala 列表(或其他序列)中创建一个 JSON 数组,所以
List.fill(3)(()).asJson
是一个 JSON 值,它是一个 JSON 数组三个空的 JSON 对象。
Lastly, circe also knows how to create a JSON object out of a Scala Map
where the keys are strings and the value type is something it knows how to encode.最后,circe 还知道如何从 Scala
Map
创建一个 JSON 对象,其中键是字符串,值类型是它知道如何编码的东西。 This means we can create a map of type Map[String, io.circe.Json]
and call asJson
on it to get a JSON value that's a JSON object containing the fields represented by the map.这意味着我们可以创建一个
Map[String, io.circe.Json]
类型的Map[String, io.circe.Json]
并在其上调用asJson
以获取一个 JSON 值,该值是一个包含由映射表示的字段的 JSON 对象。
There are other ways you could do this in circe that might be nicer depending on your exact use case, including the following:根据您的具体用例,还有其他方法可以在 circe 中执行此操作,这些方法可能会更好,包括以下内容:
case class Fields(Field1: List[Unit], Field2: List[Unit], Field3: Unit)
And then:进而:
scala> import io.circe.generic.auto._
import io.circe.generic.auto._
scala> Fields(List((), (), (), ()), List((), (), ()), ()).asJson.noSpaces
res0: String = {"Field1":[{},{},{},{}],"Field2":[{},{},{}],"Field3":{}}
This approach (which uses circe's support for generic codec derivation ) is typically more idiomatic than working with JSON values directly.这种方法(使用 circe 对通用编解码器派生的支持)通常比直接使用 JSON 值更惯用。
While a little verbose you can use the play framework .虽然有点冗长,但您可以使用播放框架。 This enables to write case class objects and then directly convert them into JSON objects.
这允许编写案例类对象,然后直接将它们转换为 JSON 对象。 The following example is a little loose since you didn't say what exactly your objects look like.
以下示例有点松散,因为您没有说明对象的确切外观。
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)
...
Then you can write an implicit writer using然后你可以使用
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.