1

我正在关注 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 _)
}
4

1 回答 1

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._
于 2013-03-21T10:47:42.737 回答