【发布时间】:2021-01-19 22:36:38
【问题描述】:
大家好,我是 Scala 世界的新手,我想使用 Play Framework 创建一个简单的 REST API。我正在处理 JSON 到案例类的映射,我可能有一个愚蠢的问题。
我有一个代表UserDto 的案例类(它用于用户注册,并获取有关用户的一些基本信息)
case class UserDto(id: Option[Int], email: String, username: String, password: Option[String], confirmedPassword: Option[String])
正如 Play Framework 文档中所说,有多种方法可以将其映射到 JSON,我正在查看 automated mapping part
我的做法是
val userDtoWrites: OWrites[UserDto] = Json.writes[UserDto]
val userDtoReads: Reads[UserDto] = Json.reads[UserDto]
现在我想为我的 UserDto 添加一些验证,例如,检查电子邮件是否正确。
所以我的问题是,是否有可能创建一个仅检查电子邮件字段的 Read 并将其添加到自动生成的 Read 中?
我用 composeWith 尝试过,但在运行第二个 Read 后,它只返回电子邮件部分。
val checkEmail: String = (JsPath \ "email").read[String](email)
val checkEmailJsString: JsString = checkEmail.map(s => JsString(s))
val newRead = userDtoReads.composeWith(checkEmailJsString))
例如,当用户想要注册时:
{"email": "user@email.com", "username": "user","password": "password1234", "confirmedPassword": "password1234"}
这应该映射到:
UserDto(None, user@email.com, user, password1234, password1234)
如果一切都是正确的。如果密码不匹配或电子邮件格式错误,例如应该返回 400。
【问题讨论】:
-
为什么要采用这种方法?您可以在创建类时添加验证:
case class UserDto (...) { checkemail(email) }。这样它将被检查到这个类的所有实例,而不仅仅是从 json 创建 -
我明白你的意思,但我的想法是将此 dto 仅用作 http 层的一部分(这意味着我会将 JSON 反序列化到其中,并将数据从 User 模型复制到其中,这应该已经检查过)。而且我想使用 Play 的内置电子邮件检查功能,这样我就不必编写自己的正则表达式了。
-
我认为有一个误解,没有自动电子邮件检查,但作为 Play 验证的一部分,这里有一个 playframework.com/documentation/2.8.x/…。我想将它与自动读取结合起来,但似乎无法结合两个读取不同字段的读取。
-
val userDtoReads: Reads[UserDto] = Json.reads[UserDto]和这个val checkEmail: String = (JsPath \ "email").read[String](email) -
也许添加一个 json 输入,所需的实例输出将有助于更好地回答这个问题。