有人可以解释这段代码是如何执行的吗?
Could someone explain how is the this code executing?
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)
R
是类型变量。定义 def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R])
为:
我是一个叫unmarshallJsValue
的方法。
我需要一个可能是任何类型的参数。
我需要 Request[JsValue]
的值(大概是 JSON 实体中包含的请求)。
我需要一个函数,给定类型 R
的某个值,生成 Result
.
我需要一个值在 implicit
范围内,即类型 R
的 Reads
。换句话说,我需要一种方法将 JsValue
转换为 R
,无论 R
可能是什么。 (如果您查看 the docs for Reads
,您会注意到它的唯一方法 reads
具有此效果。)
总而言之,整个函数只是说,给我一些代码块,它从一些我知道如何转换为 JSON 的数据中生成 Result
。函数体只是尝试将 JSON 转换为所需的类型(称为 unmarshalling)。如果成功,它将运行该块。否则,您会收到 BadRequest
客户端错误。
编译器无法知道客户端在现实生活中提供的 JSON 是否可以转换为某种类型 R
,但它可能需要一个 JSON - > R
转换器,以及一些错误处理代码(如果在实际数据上失败)。
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)
R
是类型变量。定义 def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R])
为:
我是一个叫
unmarshallJsValue
的方法。我需要一个可能是任何类型的参数。
我需要
Request[JsValue]
的值(大概是 JSON 实体中包含的请求)。我需要一个函数,给定类型
R
的某个值,生成Result
.我需要一个值在
implicit
范围内,即类型R
的Reads
。换句话说,我需要一种方法将JsValue
转换为R
,无论R
可能是什么。 (如果您查看 the docs forReads
,您会注意到它的唯一方法reads
具有此效果。)
总而言之,整个函数只是说,给我一些代码块,它从一些我知道如何转换为 JSON 的数据中生成 Result
。函数体只是尝试将 JSON 转换为所需的类型(称为 unmarshalling)。如果成功,它将运行该块。否则,您会收到 BadRequest
客户端错误。
编译器无法知道客户端在现实生活中提供的 JSON 是否可以转换为某种类型 R
,但它可能需要一个 JSON - > R
转换器,以及一些错误处理代码(如果在实际数据上失败)。