首页 > 解决方案 > 给定一个键名以大写字母开头的 Json 对象,如何“读入”Scala Case Class

问题描述

这个问题基于 Scala 2.12.12

scalaVersion := "2.12.12"

使用播放 json

"com.typesafe.play" %% "play-json" % "2.9.1"

如果我有一个看起来像这样的 Json 对象:

{
   "UpperCaseKey": "some value", 
   "AnotherUpperCaseKey": "some other value" 
}

我知道我可以像这样创建一个案例类:

case class Yuck(UpperCaseKey: String, AnotherUpperCaseKey: String) 

并用这个追逐者跟进:

implicit val jsYuck = Json.format[Yuck]

当然,这将给我reads[Yuck]writes[Yuck]来自 Json 的两者。

我问这个是因为我有一个用例,我不是决定键大小写的人,并且我收到了一个 Json 对象,该对象充满了以大写字母开头的键。

在这个用例中,我将不得不阅读并转换数百万个它们,因此性能是一个问题。

我研究了@JsonAnnotations 和 Scala 的转换器。前者似乎没有太多在现场级别的 Scala 中使用的文档,而后者似乎是很多样板文件,如果我只知道如何用另一种方式可能会非常简单......

请记住,当您回答这个问题时,一些键将被命名为:

XXXYyyyyZzzzzz

因此,预定义的 Snake/Camel 大小写转换将不起作用。

编写自定义转换似乎是一种选择,但不确定如何使用 Scala 做到这一点。

有没有办法任意请求 Json 读取将获取 Key并将其与Scala 案例类"XXXYyyyZzzz"中标记的字段匹配?"xxxYyyyZzzz"

为了清楚起见,我可能还需要将名为的 Json 键转换为或至少知道如何转换"AbCdEf"为字段标签"fghi"

标签: scalaplay-json

解决方案


只需使用提供PascalCase的 .

case class Yuck(
  upperCaseKey: String,
  anotherUpperCaseKey: String)

object Yuck {
  import play.api.libs.json._

  implicit val jsonFormat: OFormat[Yuck] = {
    implicit val cfg = JsonConfiguration(naming = JsonNaming.PascalCase)

    Json.format
  }
}

play.api.libs.json.Json.parse("""{
   "UpperCaseKey": "some value", 
   "AnotherUpperCaseKey": "some other value" 
}""").validate[Yuck]
// => JsSuccess(Yuck(some value,some other value),)

play.api.libs.json.Json.toJson(Yuck(
  upperCaseKey = "foo",
  anotherUpperCaseKey = "bar"))
// => JsValue = {"UpperCaseKey":"foo","AnotherUpperCaseKey":"bar"}

推荐阅读