当前位置: 首页 > 面试题库 >

播放2 JSON格式中缺少属性的默认值

武博艺
2023-03-14
问题内容

我在play 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"}

但是,从中读取会由于缺少“ / status”路径而产生JsError。

如何提供具有最小噪声的默认设置?

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


问题答案:

播放2.6

按照@CanardMoussant的回答,从Play 2.6开始,对play-
json宏进行了改进,并提出了多个新功能,包括在反序列化时使用默认值作为占位符:

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

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

播放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 Transformer,并将其与宏生成的Reads结合起来。变压器通过以下方法生成:

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实例,并应用默认值。

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

  • 默认密钥名称在字符串中,不会被重构获取
  • 默认值是重复的,如果在一个位置更改,则需要在另一位置手动更改


 类似资料:
  • 我使用的是Json。net将对象序列化到数据库。 我向类中添加了一个新属性(该属性在数据库的json中缺失),我希望新属性在json中缺失时具有默认值。 我尝试了DefaultValue属性,但它不起作用。我正在使用私有setter和构造函数来反序列化json,因此在构造函数中设置属性的值将不起作用,因为有一个带有该值的参数。 以下是一个例子: 我预计年龄是5岁,但现在是零岁。 有什么建议吗?

  • 我有一个类,它用Data合同和Data会员属性进行了注释。一些成员被标记为。当我通过Json的线路序列化实例时。NET,并且所需的对象成员具有空值,然后它们的序列化值在输出中丢失(这显然相当于在JSON中为空)。我没意见。 我创建了一种“echo”服务,它返回作为响应发送给它的数据。因此,此服务接收缺少成员的JSON(或空成员,具体取决于您如何看待它),然后将其发送回我的JSON。NET客户端。通

  • 本文向大家介绍C#属性的默认值,包括了C#属性的默认值的使用技巧和注意事项,需要的朋友参考一下 示例 可以使用初始化程序(C#6)设置默认值 如果它是只读的,则可以返回如下值:            

  • 问题内容: C#具有用于声明和使用属性的语法。例如,可以声明一个简单的属性,如下所示: 也可以在属性中添加一些逻辑,如下所示: 无论是否具有逻辑,属性的使用方式与字段相同: 我对Java或C#都不陌生-我已经使用了很多东西,而且我总是想念Java中使用属性语法。我在这个问题中读到“在Java7中或将来几乎不可能添加属性支持”,但是坦率地说,我发现在讨论,论坛,博客,评论和JSR中需要挖掘太多的工作

  • 20.1 属性默认值 Spring Boot支持的一些库使用缓存来提高性能。例如,模板引擎会缓存已编译的模板,以避免重复解析模板文件。此外,Spring MVC可以在服务静态资源时将HTTP缓存的头部添加到响应中。 虽然缓存功能对生产环境非常有益,但在开发过程中可能会产生反作用,使您无法看到程序中刚刚做出的更改。由于这个原因,spring-boot-devtools默认会禁用那些缓存选项。 缓存选

  • 我正在VSCode中使用OpenAPI 3编写一个API文档,扩展为OpenAPI(Swagger)Editor v4.9.1。直到今天它都运行良好-突然我的文档在所有模式声明中充满了“属性”错误。错误是: