Scala 如何在Play 2.0中转换提交的json?

Scala 如何在Play 2.0中转换提交的json?,scala,playframework-2.0,Scala,Playframework 2.0,我正在尝试使用Play2.0构建一个RESTAPI。我有一个User case类,它包含一些不应该由updateMember方法更新的字段(如用户名和密码) 是否有一种处理多个选项的有效方法,因为request.body.asJson返回一个选项[JsValue],而我的用户查找也返回一个选项: package controllers.api import org.joda.time.LocalDate import play.api.Play.current import play.api.

我正在尝试使用Play2.0构建一个RESTAPI。我有一个User case类,它包含一些不应该由updateMember方法更新的字段(如用户名和密码)

是否有一种处理多个选项的有效方法,因为
request.body.asJson
返回一个选项[JsValue],而我的用户查找也返回一个选项:

package controllers.api

import org.joda.time.LocalDate
import play.api.Play.current
import play.api.db.slick.{DB, Session}
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.functional.syntax._
import models.{Gender, User, UserId}
import repositories.UserRepository

object Member extends Controller {
  def updateMember(id: Long) = Action {
DB.withSession {
  implicit session: Session =>

    val json: JsValue = request.body.asJson              // how to deal with this?

    val repository = new UserRepository
    repository.findById(new UserId(id)).map {
      user =>
        def usernameAppender = __.json.update(
          __.read[JsObject].map { o => o ++ Json.obj("username" -> user.username) }
        )

        json.transform(usernameAppender)              // transform not found

        Ok("updated")
    }.getOrElse(NotFound)
  }
 }
}
我可以将
map
调用移动到我试图解析请求的位置,但是在那里,我想我需要在用户选项上添加另一个map,就像我已经有的那样。因此,在这种样式中,我需要每个选项都有一个
映射


在FP中有没有更好的方法来处理这样的多个选项?

您基本上是在处理嵌套的单子,处理这种选项的主要工具是
flatMap
,特别是如果两个选项都是
None
对您的程序具有相同的语义含义:

request.body.asJson.flatMap { requestJson =>
  val repository = new UserRepository
  repository.findById(new UserId(id)).map { user =>
    def usernameAppender = __.json.update(
      __.read[JsObject].map { o => o ++ Json.obj("username" -> user.username) }
    )

    requestJson.transform(usernameAppender)

    Ok("updated") // EDIT: Do you not want to return the JSON?
  }
}.getOrElse(NotFound)
但是也可能是这样的情况,您的
None
s具有不同的含义,在这种情况下,您可能只想进行模式匹配,并分别处理错误情况:

request.body.asJson match { 
  case Some(requestJson) =>
    val repository = new UserRepository
    repository.findById(new UserId(id)).map { user =>
      def usernameAppender = __.json.update(
        __.read[JsObject].map { o => o ++ Json.obj("username" -> user.username) }
      )

      requestJson.transform(usernameAppender)

      Ok("updated")
    }.getOrElse(NotFound)
  case None => BadRequest // Or whatever you response makes sense for this case
}