如何在Scala中创建JSON对象?

12

首先,我在Google和StackOverflow上搜索了很多像这样的问题,但我没有找到任何有用的答案(令我大为惊讶)。

我看到了一些关于Play框架如何在Java中创建JSON数组如何在Java中创建JSON对象的内容,但我不想使用Play框架,而且我也不知道在Scala和Java中创建JSON对象是否有所不同。

以下是我想要创建的JSON。稍后,我将把对象转换为字符串通过POST请求发送它(通过API调用)。

{
    "start_relative": {
        "value": "5",
        "unit": "years"
    },
    "metrics": [
        {
        "name": "DP_391366" # S-Temperature - Celsius
        },
        {
            "name": "DP_812682" # Sensor-A4 Luminosity
        }
    ]
}

我该如何在Scala中实现类似的操作?


不太清楚你的问题。你是想从Scala类转换成JSON字符串吗?你能发布一下你要转换的Scala类/对象吗? - djechlin
不,我不想将Scala类转换为JSON字符串。我想从Scala创建一个有效的JSON。 - Paladini
我只需要使用Scala编程语言创建一个有效的JSON字符串。稍后,我将使用这个有效的JSON字符串通过POST请求发送到API。 - Paladini
1
@FernandoPaladini,您所谈论的是序列化,它涉及将数据结构(即对象)编程转换为JSON字符串。您可以手动完成此操作,但使用现有库要比手动更容易且更快。 - 2rs2ts
2
Scala json库概述:https://dev59.com/Cmsz5IYBdhLWcg3wNVAR#14442630 - Peter Neyens
显示剩余2条评论
2个回答

14
你应该使用一个处理序列化/反序列化的库。我建议在Spray JsonPlay Json之间选择。
我先向你解释一下使用Play的过程,它与Spray非常相似。
假设你有一个类和一个包含实例和json字符串的对象:
case class MyClass(id: Int,
                   name: String,
                   description: String)

object Data {
  val obj: MyClass = MyClass(1, "me", "awesome")
  val str: String =
      """
        |{
        | "id": 1,
        | "name": "me",
        | "description": "awesome"
        |}
      """.stripMargin
}

为了对 MyClass 进行序列化/反序列化,您需要一个隐式格式化程序,专门针对此类对象,在 Play 中创建包含此格式化程序的对象。

trait MyClassPlayProtocol {
  implicit val formatAbility = Json.format[Ability]
}
object MyClassPlayProtocol extends MyClassPlayProtocol

序列化/反序列化的过程大概是这样:

object PlayData {

  import play.api.libs.json.JsValue
  import play.api.libs.json.Json
  import MyClassPlayProtocol._
  import General._

  val str2Json: JsValue = Json.parse(str)
  val obj2Json: JsValue = Json.toJson(obj)

  val json2Str: String = Json.stringify(str2Json)
  val json2Obj: MyClass = obj2Json.as[MyClass]
}

Spray中,协议将如下所示:

trait MyClassSprayProtocol extends DefaultJsonProtocol {
  implicit val myClassFormat = jsonFormat3(MyClass)
}
object MyClassSprayProtocol extends MyClassSprayProtocol

以及序列化/反序列化:

object SprayData {

  import spray.json._
  import MyClassSprayProtocol._
  import General._

  val str2Json: JsValue = str.parseJson
  val obj2Json: JsValue = obj.toJson

  val json2Str: String = str2Json.compactPrint
  val json2Obj: MyClass = obj2Json.convertTo[MyClass]
}

正如你所看到的,主要是在这两者之间进行选择。两者都得到了改进,并且可能在不久的将来会有更多的改进。

根据基准测试,你会发现其中一个比另一个快几毫秒(通常是Spray)。

就我个人而言,在工作中我使用Spray,在一些个人项目中我使用Play,我不能说我从一个项目中找到了与另一个有根本不同的东西。

编辑:

最终回答你的问题,要将MyClass转换为String(序列化),你可以像这样操作:

PLAY:  Json.stringify(Json.toJson(myClass))
SPRAY: myClass.toJson.compactPrint

然后是反序列化:

PLAY:  Json.parse(string).as[MyClass]
SPRAY: myClass.parseJson.convertTo[MyClass]

3

如果您不想自己动手,需要使用库,则有以下几种选择:

注意:如果要在Scala中使用Java Gson库,由于它们不了解“集合”,因此这个很酷的Java Gson库会失去很多神奇之处。因此,如果要使用此库,则必须将“Scala列表”转换为java.util.List,然后再使用Gson。


1
你也可以使用Jackson与Scala模块一起使用。 - 2rs2ts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接