为List集合创建隐式json读取,这可能会从输入json中丢失

时间:2013-03-19 00:18:32

标签: json scala playframework-2.1 salat

我正在关注play-salat(github.com/leon/play-salat)为json输入创建模型并保存到mongodb。如何为输入json中可能缺少的List集合创建隐式json读取?如果输入json中缺少“位置”,则以下代码会给出验证错误。

case class LIProfile(
  id: ObjectId = new ObjectId,
  positions: List[Position] = Nil
)

object LIProfile extends LIProfileDAO with LIProfileJson

trait LIProfileDAO extends ModelCompanion[LIProfile, ObjectId] {
  def collection = mongoCollection("liprofiles")
  val dao = new SalatDAO[LIProfile, ObjectId](collection) {}

  // Indexes
  collection.ensureIndex(DBObject("emailAddress" -> 1), "li_profile_email", unique = true)

  // Queries
  def findOneByEmail(email: String): Option[LIProfile] = dao.findOne(MongoDBObject("emailAddress" -> email))
}


trait LIProfileJson {

  implicit val liprofileJsonWrite = new Writes[LIProfile] {
    def writes(p: LIProfile): JsValue = {
      Json.obj(
        "id" -> p.id,
        "positions" -> p.positions
      )
    }
  }
  implicit val liprofileJsonRead = (
    (__ \ 'id).read[ObjectId] ~
    (__ \ 'positions).read (
            (__ \ 'values).read[List[Position]]
            ) 
  )(LIProfile.apply _)
}

1 个答案:

答案 0 :(得分:2)

使用readNullable检索Option并将其映射到包含的列表或空列表。

implicit val liprofileJsonRead = (
  (__ \ 'id).read[ObjectId] ~
  (__ \ 'positions).readNullable (
    (__ \ 'values).read[List[Position]]
  ).map {
    case Some(l) => l
    case None => Nil
  }
)(LIProfile)

甚至更短:

implicit val liprofileJsonRead = (
  (__ \ 'id).read[ObjectId] ~
  (__ \ 'positions).readNullable (
    (__ \ 'values).read[List[Position]]
  ).map { l => l.getOrElse(Nil) }
)(LIProfile)

我不太清楚你真正需要的输入,我的代码编译使用:

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