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
)
}
}
创建用户传递给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)
答案 0 :(得分:1)
R
是一个类型变量。定义def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R])
读作:
我称之为unmarshallJsValue
。
我需要一个可能是任何东西的类型参数。
我需要值Request[JsValue]
(可能是一个JSON实体请求)。
我需要一个函数,给定R
类型的值,产生Result
。
我要求implicit
范围内的值为类型Reads
的{{1}}。换句话说,我需要一种方法将R
转换为JsValue
,无论R
可能是什么。 (如果你看the docs for Reads
,你会注意到它唯一的方法R
会产生这种影响。)
总而言之,整个函数只是说,给我一些代码块,从我知道如何从JSON转换的某些数据产生reads
。该函数的主体只是尝试将JSON转换为所需的类型(称为解组)。如果成功,则运行该块。否则,您会收到Result
客户端错误。
编译器无法知道客户端在现实生活中提供的JSON是否可以转换为某种类型BadRequest
,但它可能需要JSON - > R
转换器,以及一些错误处理代码,如果它在真实数据上失败。