使用 Play 以 JSON 形式返回验证错误!框架
Posted
技术标签:
【中文标题】使用 Play 以 JSON 形式返回验证错误!框架【英文标题】:Returning validation errors as JSON with Play! framework 【发布时间】:2011-11-27 17:32:36 【问题描述】:我想构建一个应用程序,其中通过 Ajax 提交表单而无需重新加载完整的页面。要显示服务器端验证错误,服务器应将验证错误作为 JSON 和适当的 HTTP 状态 (400) 返回。
如何通过 Play 实现这一点!框架?
【问题讨论】:
【参考方案1】:您是否正在寻找比这更复杂的东西:
public static void yourControllerMethod()
... // your validation logic
if (validation.hasErrors())
response.status = 400;
renderJSON(validation.errors);
【讨论】:
【参考方案2】:查看 samples-and-tests 文件夹和验证应用程序。其中一个示例 (Sample7) 使用名为 jQueryValidate 的自定义标记(您可以在示例中看到)完全按照您的要求进行操作。
如果你尝试这个示例,你会发现它是一个非常简洁的解决方案,在我看来,这种验证方法应该是 Core Playframework 的一部分。
【讨论】:
【参考方案3】:在 Play Framework 2.x 和 Scala 中,您可以使用以下示例:
import play.api.libs.json._
case class LoginData(email : String, password: String)
implicit object FormErrorWrites extends Writes[FormError]
override def writes(o: FormError): JsValue = Json.obj(
"key" -> Json.toJson(o.key),
"message" -> Json.toJson(o.message)
)
val authForm = Form[LoginData](mapping(
"auth.email" -> email.verifying(Constraints.nonEmpty),
"auth.password" -> nonEmptyText
)(LoginData.apply)(LoginData.unapply))
def registerUser = Action implicit request =>
authForm.bindFromRequest.fold(
form => UnprocessableEntity(Json.toJson(form.errors)),
auth => Ok(Json.toJson(List(auth.email, auth.password)))
)
我看到这个问题标有 java 标签,但我想这可能对 Scala 开发人员有用。
【讨论】:
上述的导入语句应该包括import play.api.libs.json._
,并且当您转换表单错误时,隐式对象很可能作为可重用实体存在于您的控制器中(注意表单点错误)而不是任何东西案例类本身独有。一旦你知道了这一切,那就很明显了,但 *** 可以帮助那些不知道的人:)
感谢提示,我已添加导入。【参考方案4】:
为了对您的请求执行服务器端验证,Play 框架提供了一个内置验证模块,该模块在后台使用 Hibernate Validator。
假设你有一个对应传入请求的 POJO 类,
import play.data.validation.Constraints;
public class UserRequest
@Constraints.Required
private String userName;
@Constraints.Required
private String email;
可以从控制器执行请求验证,如下所示。
public class UserController extends Controller
Form<UserRequest> requestData = Form.form(UserRequest.class).bindFromRequest();
if(requestData.hasErrors())
return badRequest(requestData.errorsAsJson());
else
//... successful validation
如果请求验证失败,将产生以下响应。
"userName": [
"This field is required"
],
"email": [
"This field is required"
]
除此之外,您还可以将多个约束应用于类字段。其中一些是,
@Constraints.Min() @Constraints.Max() @Constraints.Email【讨论】:
【参考方案5】:既然您提到了[java]
标签,我暗示您使用的是Java 版本的Play 框架。此外,我看不到任何指向无法使用任何第三方库的前提。基于此,您可以使用validol 验证库,鼓励declarative style。
考虑以下请求,它可以是一种注册请求,但为简洁起见,由单个 payment
块组成:
"payment":
"card_number":12345612341234,
"expires_at":"12/29"
验证逻辑是一个不可变的表达式,表示为一个类:
public class ValidatedRegistrationRequest implements Validatable<RegistrationRequest>
private String jsonRequestString;
private Connection dbConnection;
public ValidatedRegistrationRequest(String jsonRequestString, Connection dbConnection)
this.jsonRequestString = jsonRequestString;
this.dbConnection = dbConnection;
@Override
public Result<RegistrationRequest> result() throws Exception
return
new FastFail<>(
new WellFormedJson(
new Unnamed<>(Either.right(new Present<>(this.jsonRequestString)))
),
requestJsonObject ->
new UnnamedBlocOfNameds<>(
List.of(
new FastFail<>(
new IsJsonObject(
new Required(
new IndexedValue("payment", requestJsonObject)
)
),
paymentJsonObject ->
new NamedBlocOfNameds<>(
"payment",
List.of(
new ValidThrueIsNotExpired(
new AsString(
new Required(
new IndexedValue("valid_thru", paymentJsonObject)
)
)
),
new CardNumberIsNotBlacklisted(
new CardNumberSatisfiesLuhnAlgorithm(
new Required(
new IndexedValue("card_number", paymentJsonObject)
)
),
this.dbConnection
)
),
Payment.class
)
)
),
RegistrationRequest.class
)
)
.result()
;
没有方便的方法在 SO 上显示行号,但这里是上面代码的line-by-line analysis。
与 JSON Schema 相比,这种方法通常需要更少的行,并且在用于非常复杂的请求时确实非常出色。
【讨论】:
以上是关于使用 Play 以 JSON 形式返回验证错误!框架的主要内容,如果未能解决你的问题,请参考以下文章
Struts2中如何将验证的错误信息用提示框的形式显示出来?
以简单的形式获取 error_notification 文本而不生成验证错误
使用 websocketpp 以 json 形式返回的数据,但使用 messagepack 以 Blob 形式返回的数据