0

createUser 或 updateUser 如何使用 unmarshalValueJs 函数并传递参数。

    package controllers.user

import play.api._
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
import services.user.UserServiceComponent
import domain.user.User

trait UserController extends Controller {
    self: UserServiceComponent =>0

def emailAlreadyExists(implicit reads: Reads[String]) =
    Reads[String](js => reads.reads(js).flatMap { e =>
      userService.tryFindByEmail(e).map(_ => JsError("error.custom.emailAlreadyExists")).getOrElse(JsSuccess(e))
    })

implicit val userReads = (__ \ "email").read[String](email andKeep emailAlreadyExists)
                                       .map(resource => UserResource(resource))

implicit val userWrites = new Writes[User] {
    override def writes(user: User): JsValue = {
        Json.obj(
            "id" -> user.id,
            "email" -> user.email
        )
    }
}

什么 create User 传递给 unmarshalJsValue?资源从哪里来?

def createUser = Action(parse.json) {request =>
    unmarshalJsValue(request) { resource: UserResource =>
        val user = User(Option.empty, resource.email)
        userService.createUser(user)
        Created
    }
}

def updateUser(id: Long) = Action(parse.json) {request =>
    unmarshalJsValue(request) { resource: UserResource =>
        val user = User(Option(id), resource.email)
        userService.updateUser(user)
        NoContent
    }
}

def findUserById(id: Long) = Action {
    val user = userService.tryFindById(id)
    if (user.isDefined) {
        Ok(Json.toJson(user))
    } else {
        NotFound
    }
}

def deleteUser(id: Long) = Action {
    userService.delete(id)
    NoContent
}

这里的R是什么?什么被传回给 createUser?

    def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R]): Result =
        request.body.validate[R](rds).fold(
            valid = block,
            invalid = e => {
                val error = e.mkString
                Logger.error(error)
                BadRequest(error)
            }
        )

}

case class UserResource(email: String)
4

1 回答 1

1

R是一个类型变量。定义def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R])如下:

  • 我是一个方法叫unmarshallJsValue.

  • 我需要一个可能是任何东西的类型参数。

  • 我需要一个值Request[JsValue](大概是一个 JSON 实体中的请求)。

  • 我需要一个函数,给定一些 type 的值R,生成一个Result.

  • 我需要一个值在for 类型的implicit范围内。换句话说,我需要一种将 a 转换为 a 的方法,无论发生什么。(如果您查看的文档,您会注意到它的唯一方法,具有此效果。)ReadsRJsValueRRReadsreads

总而言之,整个函数只是说,给我一些代码块,它可以Result从我知道如何从 JSON 转换为的一些数据中生成一个。该函数的主体只是尝试将 JSON 转换为所需的类型(称为unmarshalling)。如果成功,它将运行该块。否则,您会收到BadRequest客户端错误。

编译器无法知道客户端在现实生活中提供的 JSON 是否可以转换为某种类型R,但它可能需要一个 JSON ->R转换器,以及一些错误处理代码(如果它在真实数据上失败)。

于 2016-10-22T06:15:17.120 回答