gpt4 book ai didi

json - play 2 JSON 格式中缺少的属性的默认值

转载 作者:IT老高 更新时间:2023-10-28 12:49:17 26 4
gpt4 key购买 nike

我在玩 scala 中有一个等效于以下模型的模型:

case class Foo(id:Int,value:String)
object Foo{
import play.api.libs.json.Json
implicit val fooFormats = Json.format[Foo]
}

对于下面的 Foo 实例

Foo(1, "foo")

我会得到以下 JSON 文档:

{"id":1, "value": "foo"}

此 JSON 被持久化并从数据存储中读取。现在我的要求发生了变化,我需要向 Foo 添加一个属性。该属性有一个默认值:

case class Foo(id:String,value:String, status:String="pending")

写入 JSON 不是问题:

{"id":1, "value": "foo", "status":"pending"}

然而,从它读取会产生一个 JsError,因为缺少“/status”路径。

如何提供噪音最小的默认值?

(ps:我有一个答案,我将在下面发布,但我对此并不满意,并会投票并接受任何更好的选择)

最佳答案

玩 2.6+

根据 @CanardMoussant's answer ,从 Play 2.6 开始,play-json 宏得到了改进,并提出了多项新功能,包括在反序列化时使用默认值作为占位符:

implicit def jsonFormat = Json.using[Json.WithDefaultValues].format[Foo]

对于低于 2.6 的游戏,最好的选择仍然是使用以下选项之一:

play-json-extra

我发现了一个更好的解决方案,可以解决我使用 play-json 的大部分缺点,包括问题中的那个:

play-json-extra它在内部使用 [play-json-extensions] 来解决这个问题中的特定问题。

它包含一个宏,它会自动在序列化器/反序列化器中包含缺失的默认值,从而使重构更不容易出错!

import play.json.extra.Jsonx
implicit def jsonFormat = Jsonx.formatCaseClass[Foo]

您可能想查看更多内容:play-json-extra

Json 转换器

我目前的解决方案是创建一个 JSON 转换器并将其与宏生成的读取结合起来。变压器是通过以下方法生成的:

object JsonExtensions{
def withDefault[A](key:String, default:A)(implicit writes:Writes[A]) = __.json.update((__ \ key).json.copyFrom((__ \ key).json.pick orElse Reads.pure(Json.toJson(default))))
}

然后格式定义变成:

implicit val fooformats: Format[Foo] = new Format[Foo]{
import JsonExtensions._
val base = Json.format[Foo]
def reads(json: JsValue): JsResult[Foo] = base.compose(withDefault("status","bidon")).reads(json)
def writes(o: Foo): JsValue = base.writes(o)
}

Json.parse("""{"id":"1", "value":"foo"}""").validate[Foo]

确实会生成一个应用了默认值的 Foo 实例。

我认为这有两个主要缺陷:

  • 默认键名在字符串中,不会被重构提取
  • 默认值是重复的,如果在一处更改,则需要在另一处手动更改

关于json - play 2 JSON 格式中缺少的属性的默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20616677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com