如何使用Json.reads将JSON反序列化为具有可选构造函数参数的case类

时间:2014-12-25 17:13:06

标签: json scala playframework

给出以下案例类和JSON

case class Profile(name: String, `type`: String, value: String, sort: Long = 0)

val json_string = """[
  {"name": "Birthday", "type": "DateTime", "value": "12/25/1990"},
  {"name": "Fullname", "type": "String", "value": "Birthday Boy"}
]"""

以下电话:

val profiles = Json.parse(json_string).as[Seq[Profile]]

异常结果:

JsResultException(errors:List(((0)/sort,List(ValidationError(error.path.missing,WrappedArray()))), ((1)/sort,List(ValidationError(error.path.missing,WrappedArray())))))

如果我将一个sort键添加到我的JSON字符串,则反序列化按预期工作。为什么案例类中的sort的默认值不会“启动”并允许反序列化?

我正在使用JsMacroInception来定义读/写

   val implicit profileReader = Json[Profile].reads
   val implicit profileWriter = Json[Profile].writes

我可以使用阅读器来支持可选的构造函数参数吗?

2 个答案:

答案 0 :(得分:1)

您需要对选项进行排序,但是null或非包含的值将为none。如果这不起作用,那么你必须编写自己的读取来设置默认值,以防空/缺少排序

答案 1 :(得分:1)

JSON读取宏在生成Reads[Profile]时不会考虑默认构造函数值。因此,如果您仍想使用该宏,则唯一的选择是将sort设为Option[Long]。如果你想提供一个默认值,那么我建议你使用JSON组合器:

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val reads: Reads[Profile] = (
    (__ \ "name").read[String] and 
    (__ \ "type").read[String] and 
    (__ \ "value").read[String] and 
    (__ \ "sort").read[Long].orElse(Reads.pure(0L))
)(Profile.apply _)

如果在JSON对象中找不到sort,则会应用orElse,在这种情况下,我会使用Reads.pure来提供固定的默认值。