Scala playfamework - 如何用另一个 JSON 字符串包装?

Scala playfamework - how to wrap one JSON string with another?

我有来自两个不同 API 端点的 JSON 数据。第一个 JSON 包含有关商店的数据,第二个包含有关交易(销售)的数据。

对于每个商店 ID,我得到一个交易数组并将其解析为 JsValue。所以我有一个 store Jsvalue 代表特定商店和 transactions JsValue,代表商店的交易数组。然后我将 JsValues 字符串化:

(Json.stringify(storeJsValue), Json.stringify(transactionsJson))

上述 Array[(String, String)] 的字符串化 JsValues 的打印结果:

({"store_id":"01","name":"Store_1"}, [{"saleId": 12, "name": "New name1", "saleType": "New Type1"]}, {"saleId": 222, "name": "Some name1", "saleType": "SomeType5"})
({"store_id":"02","name":"Store_2"}, [{"saleId": 123, "name": "New name2", "saleType": "New Type2"}])
({"store_id":"03","name":"Store_3"}, [{"saleId": 1234, "name": "New name3", "saleType": "New Type3"}, {"saleId": 333, "name": "Some name3", "saleType": "SomeType3"}])

最后,我想生成一个结果字符串,以便商店数据包装其交易数据,如下所示:

"{store:\"storeJson\",transactions:\"+ transactionsJson + "}"

使用 Play Json 实现此目的的最佳方法是什么?

一种方法是将 json 转换为对象,创建一个具有属性 "store" 和 "transactions" 的新对象,然后再次将其转换为 JSON。

这样你会得到:

{ 
  "store": {
    "store_id":"01",
    "name":"Store_1"
  },
  "transactions": [
    {
        "saleId": 12,
        "name": "New name1",
        "saleType": "New Type1"
    }, 
    {
        "saleId": 222,
        "name": "Some name1", 
        "saleType": "SomeType5"
    }
  ]
}

你的class:

case class MyClass( store : Store, transactions : Array[Sales]) {
    .....
}

我已经达到了预期的效果。

val store = Json.stringify(storeJsValue)
val transactions = Json.stringify(transactionsJsValue)
val storeWithTransactions: String = s"{store: $store , transactions: $transactions}"

这样我就得到了一个字符串,其中包含商店及其所有交易的数据。所以我只是遍历商店,并为每个商店 Id 从另一个端点获取其交易。然后将 storetransactions 的字符串化 JsValues 连接起来,将生成的字符串收集到 Array[String] 中。

在 Play 中,您可以使用 Json Reads/Writes 助手将 case class 转换为 Json,反之亦然。因此,对于您的示例:

case class Store(store_id: String, name: String)

然后如果你有一个 Json 并想把它变成 Store 案例 class 你需要一个 'reader':

val storeReads: Reads[Store] = Json.reads[Store]

之后就可以把Json的内容读成String,转成大小写class(假设storeJson是一个包含[=44的内容的val =]):

val toStoreCaseClass: JsResult[Store] = Json.fromJson[Store](json.parse(storeJson))

如果你想把大小写class变成Json,那么你使用写:

val storeWrites: OWrites[Store] = Json.writes[Store]

现在假设您有一个 Store 类型的 val storeInstance,您通过以下行将其转换为 Json:

Json.toJson(storeInstance)

您可以对交易做同样的事情。

好的 现在你有了大小写 classes,你可以使用常用的集合命令(例如 mapfilter 等)将它们变成你想要的任何格式。 ).你甚至可以有一个额外的更通用的案例 class 来保存你想要实现的格式(及其 read/writes);然后做你的数据操作,最后变成Json。

你有两个 json 值,你可以用它们创建一个新对象:

val storeWithTransactions: String = Json.stringify(Json.obj(
       "store" -> storeJsValue,
       "transactions" -> transactionsJsValue))