如何“读取”给定的Json对象的Scala Case类,该对象的键名以大写字母开头
这个问题基于Scala 2.12.12 标度厌恶度:=2.12.12 使用play-json com.typesafe.play%%播放json%2.9.1 如果我有一个Json对象,如下所示:如何“读取”给定的Json对象的Scala Case类,该对象的键名以大写字母开头,scala,play-json,Scala,Play Json,这个问题基于Scala 2.12.12 标度厌恶度:=2.12.12 使用play-json com.typesafe.play%%播放json%2.9.1 如果我有一个Json对象,如下所示: XXXYyyyyZzzzzz { 大写键:一些值, 另一个UpperCaseKey:其他值 } 我知道我可以创建这样的案例类: 大小写类YuckUpperCaseKey:String,另一个UpperCaseKey:String 然后用这个追踪器跟进: 隐式val jsYuck=Json.format
XXXYyyyyZzzzzz
{
大写键:一些值,
另一个UpperCaseKey:其他值
}
我知道我可以创建这样的案例类:
大小写类YuckUpperCaseKey:String,另一个UpperCaseKey:String
然后用这个追踪器跟进:
隐式val jsYuck=Json.format[Yuck]
当然,这会让我在Json中读[Yuck]和写[Yuck]
我这样问是因为我有一个用例,在这个用例中,我不是决定键大小写的人,我被交给了一个Json对象,其中充满了以大写字母开头的键
在这个用例中,我将不得不读取和转换数百万个,因此性能是一个问题
我研究了@JsonAnnotations和Scala的变形金刚。前者似乎没有太多用于Scala领域级的文档,而后者似乎是很多样板文件,如果我只知道如何
请记住,在回答此问题时,某些密钥的名称如下:
XXXYyyyyZzzzzz
因此,预定义的Snake/Camel大小写转换将不起作用
编写自定义转换似乎是一种选择,但不确定如何使用Scala实现
有没有一种方法可以任意请求Json读取将采用xxxyyyzzz键并将其与Scala case类中标记为xxxyyyzzz的字段相匹配
为了清楚起见,我可能还需要将一个名为AbCdEf的Json键转换成或至少知道如何转换成标记为fghi的字段。只需使用提供的PascalCase即可
只需使用提供的PascalCase
我认为play json支持这种场景的唯一方法是定义自己的格式 假设我们有: 案例类YUCKXXXYYYYYZZZ:String,fghi:String 因此,我们可以在伴生对象上定义格式: 对象恶心{ 隐式val格式:格式[Yuck]={ __\xxxyyyyzzzzz.format[String]和uuu\ AbCdEf.format[String]Yuck.apply\uuuu,Yuck=>Yuck.xxxyyyyyzzz,Yuck.fghi } } 然后是: val jsonString={XXXYyyyZzzz:第一个值,AbCdEf:第二个值} val-yuck=Json.parsejsonString.validate[yuck] 印刷怪事 yuck.mapyuckResult=>Json.toJsonyuckResult.foreachprintln 将输出: JsSuccessYuckfirst值,second值, {xxxyyyzzzz:第一个值,AbCdEf:第二个值} 我们可以看到,xxxyyyzzz被映射到xxxyyyzzz,AbCdEf被映射到fghi 代码在上运行 另一个选择是使用usd JSONNAMINING,正如@cchantep在评论中所建议的那样。如果您定义:
object Yuck {
val keysMap = Map("xxxYyyyZzzz" -> "XXXYyyyZzzz", "fghi" -> "AbCdEf")
implicit val config = JsonConfiguration(JsonNaming(keysMap))
implicit val fotmat = Json.format[Yuck]
}
运行相同的代码将输出相同的结果。代码ru nat。我认为播放json支持这种场景的唯一方法是定义自己的格式 假设我们有: 案例类YUCKXXXYYYYYZZZ:String,fghi:String 因此,我们可以在伴生对象上定义格式: 对象恶心{ 隐式val格式:格式[Yuck]={ __\xxxyyyyzzzzz.format[String]和uuu\ AbCdEf.format[String]Yuck.apply\uuuu,Yuck=>Yuck.xxxyyyyyzzz,Yuck.fghi } } 然后是: val jsonString={XXXYyyyZzzz:第一个值,AbCdEf:第二个值} val-yuck=Json.parsejsonString.validate[yuck] 印刷怪事 yuck.mapyuckResult=>Json.toJsonyuckResult.foreachprintln 将输出: JsSuccessYuckfirst值,second值, {xxxyyyzzzz:第一个值,AbCdEf:第二个值} 我们可以看到,xxxyyyzzz被映射到xxxyyyzzz,AbCdEf被映射到fghi 代码在上运行 另一个选择是使用usd JSONNAMINING,正如@cchantep在评论中所建议的那样。如果您定义:
object Yuck {
val keysMap = Map("xxxYyyyZzzz" -> "XXXYyyyZzzz", "fghi" -> "AbCdEf")
implicit val config = JsonConfiguration(JsonNaming(keysMap))
implicit val fotmat = Json.format[Yuck]
}
运行相同的代码将输出相同的结果。代码ru nat。感谢您提供的示例代码-这对于我需要做的其他一些事情非常有用。但在本例中,它只解析第一个字母,这至少在Scala case类中为我提供了更好的字段名。但是,如果不处理我希望转换为XXXYYYYYZZZZZZZ的XXXYYYYYZZZZZZZ或我希望转换为XXXYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZXYYYYYYYZZZZZZZZZZZZZZZZZZZZZZ。。。Aka a String=>String感谢您提供的示例代码-这对于我需要做的其他一些事情非常有用。但在本例中,它只解析第一个字母,这至少在Scala case类中为我提供了更好的字段名。但是,如果不处理我希望转换为XXXYYYYYZZZZZZZ的XXXYYYYYZZZZZZZ或我希望转换为XXXYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZXYYYYYYYZZZZZZZZZZZZZZZZZZZZZZ。。。又名a String=>StringJSONNaming方法看起来更具自解释性和可维护性。问题:是否必须以这种方式定义所有键或仅定义例外?它能和骆驼皮箱混合/搭配吗/P
ascalCase/SnakeCase转换方法?假设10个键,其中2个需要例外,8个可以通过PascalCase?@Techmag,您需要定义所有键,因为幕后播放将此贴图转换为应用方法。因此,如果值计数不匹配,它将不会编译。我不认为你可以把它和任何一个Case转换混在一起,但是如果你仔细想想,两者都用是没有意义的。只需创建您想要的映射,而不是创建驼峰大小写的映射,然后将其转换为pascal大小写,或者反过来。我只是在不需要提供所有键的情况下考虑组合。如果所有键都是必需的,那么多次转换将毫无意义。感谢您对这一点的澄清。JsonNaming方法看起来更具自解释性和可维护性。问题:是否必须以这种方式定义所有键或仅定义例外?它是否可以与CamelCase/PascalCase/SnakeCase转换方法混合/匹配?假设10个键,其中2个需要例外,8个可以通过PascalCase?@Techmag,您需要定义所有键,因为幕后播放将此贴图转换为应用方法。因此,如果值计数不匹配,它将不会编译。我不认为你可以把它和任何一个Case转换混在一起,但是如果你仔细想想,两者都用是没有意义的。只需创建您想要的映射,而不是创建驼峰大小写的映射,然后将其转换为pascal大小写,或者反过来。我只是在不需要提供所有键的情况下考虑组合。如果所有键都是必需的,那么多次转换将毫无意义。谢谢你澄清这一点。