我试图像这样创建一个Json对象
{
"Field1": [{}, {}, {}, {}],
"Field2": [{}, {}, {}],
"Field3": {}
}

通常在Java中我可以通过(特别是使用google simple json)来实现这一目标
上面的结果来自不同的进程,我需要返回一个组合的json对象
我很困惑如何在Scala中实现相同的功能,我尝试了多种库和方法。我最近尝试的是json4s。我以为我可以
我认为这会像在Java中一样简单,我错过了一些明显的东西吗? (我是斯卡拉新手)。
非常感谢任何帮助。
答案 0 :(得分:1)
以下是在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)
之类的实用程序,它会创建value
重复n
次列表。这意味着List.fill(3)(())
与List((), (), ())
完全相同,我们也可以在上面使用它。
第二点更具针对性。 ()
是Scala中的一个特殊值 - 它是类型Unit
的唯一值,它只代表一个不带信息的空事物。在()
中,{}
的JSON编码为().asJson
,因此我们可以通过调用List.fill(3)(()).asJson
来创建一个空的JSON对象。
circe也知道如何从它知道如何编码的任何类型的Scala列表(或其他序列)中创建一个JSON数组,因此Map
是一个JSON值,它是一个三个空JSON的JSON数组对象。
最后,circe还知道如何从Scala Map[String, io.circe.Json]
创建一个JSON对象,其中键是字符串,值类型是它知道如何编码的东西。这意味着我们可以创建一个asJson
类型的地图,并在其上调用case class Fields(Field1: List[Unit], Field2: List[Unit], Field3: Unit)
以获取一个JSON值,该值是一个包含地图所代表的字段的JSON对象。
根据您的确切用例,还有其他方法可以做到这一点,可能会更好,包括以下内容:
scala> import io.circe.generic.auto._
import io.circe.generic.auto._
scala> Fields(List((), (), (), ()), List((), (), ()), ()).asJson.noSpaces
res0: String = {"Field1":[{},{},{},{}],"Field2":[{},{},{}],"Field3":{}}
然后:
{{1}}
这种方法(使用circe对generic codec derivation的支持)通常比直接使用JSON值更惯用。
答案 1 :(得分:1)
我使用scala module with 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)))
答案 2 :(得分:0)
虽然有点冗长,但您可以使用play framework。这使得能够编写案例类对象,然后直接将它们转换为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)