有人可以解释这段代码是如何执行的?

时间:2016-10-22 01:41:16

标签: scala playframework play-json

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)

1 个答案:

答案 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转换器,以及一些错误处理代码,如果它在真实数据上失败。