在使用Json.format函数之后,如何从具有缺少字段的客户端发送Json用于其对应的Case类

时间:2014-08-07 11:02:06

标签: json scala playframework

我有一个案例类及其伴随对象,如下所示。现在,当我发送没有id,createdAt和deletedAt字段的JSON时,因为我将它们设置在别处,我得到[NoSuchElementException: JsError.get]错误。这是因为我没有设置上面的属性。

我怎样才能做到这一点并避免错误?

case class Plan(id: String,
                companyId: String,
                name: String,
                status: Boolean = true,
                @EnumAs planType: PlanType.Value,
                brochureId: Option[UUID],
                lifePolicy: Seq[LifePolicy] = Nil,
                createdAt: DateTime,
                updatedAt: DateTime,
                deletedAt: Option[DateTime]
                )

object Plan {
   implicit val planFormat = Json.format[Plan]
   def fromJson(str: JsValue): Plan = Json.fromJson[Plan](str).get
   def toJson(plan: Plan): JsValue = Json.toJson(plan)
   def toJsonSeq(plan: Seq[Plan]): JsValue = Json.toJson(plan)
}

我从客户端发送的JSON

{
    "companyId": "e8c67345-7f59-466d-a958-7c722ad0dcb7",
    "name": "Creating First Plan with enum Content",
    "status": true,
    "planType": "Health",
    "lifePolicy": []
}

2 个答案:

答案 0 :(得分:1)

您可以引入另一个案例类来处理来自请求的序列化: 像这样

  case class NewPlan(name: String,
            status: Boolean = true,
            @EnumAs planType: PlanType.Value,
            brochureId: Option[UUID],
            lifePolicy: Seq[LifePolicy] = Nil        
            ) 

然后使用此类填充您的Plan类。

答案 1 :(得分:1)

根本问题是,当case class被实例化以表示您的数据时,它必须是良好类型的。要将示例数据添加到示例类中,类型不匹配,因为缺少某些字段。它确实试图在没有足够参数的情况下调用构造函数。

您有两个选择:

  • 您可以创建一个代表不完整数据的模型(如grotrianster建议的那样)。
  • 您可以填写可能缺少的字段Option类型。
  • 您可以自定义编写Reads的{​​{1}}部分,为缺失的值引入智能值或虚拟值。

选项3可能类似于:

Format

一旦执行此操作,如果所有其他模型的问题相同,您可以将其抽象为某些// Untested for compilation, might need some corrections val now: DateTime = ... val autoId = Reads[JsObject] { case obj: JsObject => JsSuccess(obj \ 'id match { case JsString(_) => obj case _ => obj.transform( __.update((__ \ 'id).json.put("")) andThen __.update((__ \ 'createdTime).json.put(now)) andThen __.update((__ \ 'updatedTime).json.put(now)) ) }) case _ => JsError("JsObject expected") } implicit val planFormat = Format[Plan]( autoId andThen Json.reads[Plan], Json.writes[Plan]) 工厂实用程序函数。

对于Format

,这可能稍微清晰一些
autoId