Play framework HTTP form表单数据校验

xiaoxiao2021-02-28  95

使用Play校验HTTP数据

验证保证数据是一定的值或满足特定的需求,你可以在保存Model数据到数据库之前校验数据是否正确,或直接使用HTTP参数来验证一个简单的形式。

使用Play验证是如何发挥作用的

每个request对象有它自己的Validation 对象来收集错误,这里有三种方法来定义validations;

1.在控制器方法中,直接调用控制器方法来validation 字段,你也可以访问API的play.data.validation.validation类的静态方法的一个子集。

2.添加注释的方法验证控制器的参数声明。

3.添加@Valid注释到action方法的POJO参数,并且给POJO的属性添加校验注释。

验证对象保存一个play.data.validation.Error集合对象,每一个error有两个属性;

key,这个属性帮助你确定哪一个属性引发了错误,键值可以任意设置,但在使用Play时会产生错误。它使用默认的约定,遵循java变量的名字。

message,这包含错误文本的描述,消息可以是普通消息,也可以是消息包中的键(通常用于国际化支持)。

使用第一种方法,让我们看看如何验证一个简单的HTTP参数:

public static void hello(String name) { validation.required(name); … } 此代码检查名称变量是否正确设置。如果没有,则将相应的错误添加到当前错误集合中。

您可以为需要的每个验证重复此操作:

public static void hello(String name, Integer age) { validation.required(name); validation.required(age); validation.min(age, 0); … }

验证错误消息

在验证结束时,您可以检查是否已经创建了任何错误并显示它们:

public static void hello(String name, Integer age) { validation.required(name); validation.required(age); validation.min(age, 0); if(validation.hasErrors()) { for(Error error : validation.errors()) { System.out.println(error.message()); } } } 假设名称和年龄为空,则显示:

Required Required 这是因为默认消息,定义在 $PLAY_HOME/resources/messages:

validation.required=Required 有定制的验证信息的三种方式。

1.通过在应用程序的消息文件中重新定义消息,覆盖默认消息。

2.将自定义消息作为附加的验证参数提供。

3.为一个本地化的消息提供一个消息键作为附加的验证参数。

局部验证消息

重写这些信息的最简单方法是使用相同的信息,关键的信息在您的应用程序的配置信息文件。例如:

validation.required = Please enter a value 您也可以提供其他语言的本地化,如

验证消息参数

您可以使用消息中的占位符作为错误密钥:

validation.required=%s is required 这将输出更改为:

name is required age is required 限制:当多个参数是Play不能确定正确的参数名,必须的参数使用validation.required(age) 语法校验失败,在这种情况下,必须直接指定字段名。 validation.required("age", age);

此错误键默认为参数名称,它本身就是用来查找消息的。例如,上面的hello action方法中的name参数可以本地化:

name = Customer name 这将导致输出:

Customer name is required age is required 你还可以使用   error.message(String key)方法,

Error error = validation.required(name).error; if(error != null) { System.out.println(error.message("Customer name")); } 几个内置的验证定义额外的消息参数对应的验证参数,例如,“匹配”验证为指定的正则表达式定义了第二个字符串参数,它与上面的%s占位符不同,因为它指定参数索引“2”:

validation.match=Must match %2$s 类似地,“范围”验证定义了两个附加的数字参数,索引2和3:

validation.range=Not in the range %2$d through %3$d 查看文件 $PLAY_HOME/resources/messages ,查看其它的参数。

自定义局部验证消息

验证消息在 $PLAY_HOME/resources/messages文件中使用默认的消息key,你可以指定不同的key,例如:

validation.required.em = You must enter the %s! 使用此消息的新消息键,在操作方法中进行手动验证:

validation.required(manualKey).message("validation.required.em"); 或者,在注释的消息参数中使用该键:

public static void hello(@Required(message="validation.required.em") String name) { … } 可以使用与JavaBean属性上的验证注释相同的技术:

public static void hello(@Valid Person person) { … } public class Person extends Model { @Required(message = "validation.required.emphasis") public String name; … } 自定义文字(非本地化)验证消息

如果没有定义密钥的消息,则Play消息查找仅返回消息密钥,

也就是说,如果您愿意,也可以使用字面消息而不是消息键。使用上述示例,进行手动验证:

validation.required(manualKey).message("Give us a name!"); action方法参数的注释:

public static void save(@Required(message = "Give us a name!") String name) { … } 对于JavaBean注释是:

public static void save(@Valid Person person) { … } public class Person extends Model { @Required(message = "Give us a name!") public String name; … }

在模板中验证错误

在大多数情况下,您希望在视图模板中显示错误消息。你可以在模板中使用errors对象接收他们,一些标签帮助你去显示错误信息。

让我们看一个例子:

public static void hello(String name, Integer age) { validation.required(name); validation.required(age); validation.min(age, 0); render(name, age); } 现在模板:

#{ifErrors} <h1>Oops…</h1> #{errors} <li>${error}</li> #{/errors} #{/ifErrors} #{else} Hello ${name}, you are ${age}. #{/else}

但是在实际的应用中,你想显示原始形式,因此,您将有两个动作:一个显示窗体,另一个操作句柄。

当然,验证将发生在第二个操作中,如果出现一些错误,您将不得不重定向到第一个操作。在这种情况下,您需要一个特殊的技巧来在重定向期间保持错误。使用validation.keep()方法,将会给下一个action请求保存错误集合。

让我们看看真正的样例:

public class Application extends Controller { public static void index() { render(); } public static void hello(String name, Integer age) { validation.required(name); validation.required(age); validation.min(age, 0); if(validation.hasErrors()) { params.flash(); // add http parameters to the flash scope validation.keep(); // keep the errors for the next request index(); } render(name, age); } } 与视图 view/Application/index.html一起使用。

#{ifErrors} <h1>Oops…</h1> #{errors} <li>${error}</li> #{/errors} #{/ifErrors} #{form @Application.hello()} <div> Name: <input type="text" name="name" value="${flash.name}" /> </div> <div> Age: <input type="text" name="age" value="${flash.age}" /> </div> <div> <input type="submit" value="Say hello" /> </div> #{/form} 通过在生成错误的字段旁边显示每个错误消息,可以创建更好的用户体验:

#{ifErrors} <h1>Oops…</h1> #{/ifErrors} #{form @Application.hello()} <div> Name: <input type="text" name="name" value="${flash.name}" /> <span class="error">#{error 'name' /}</span> </div> <div> Age: <input type="text" name="age" value="${flash.age}" /> <span class="error">#{error 'age' /}</span> </div> <div> <input type="submit" value="Say hello" /> </div> #{/form}

验证注释

play.data.validation包 中的注释提供了一种更简单的方法来验证错误,使用对应于每个对象方法的Validation注释,去使用validation 注释,只需注释控制器的参数:

public static void hello(@Required String name, @Required @Min(0) Integer age) { if(validation.hasErrors()) { params.flash(); // add http parameters to the flash scope validation.keep(); // keep the errors for the next request index(); } render(name, age); }

您还可以使用验证注释轻松地为模型对象的属性添加约束。然后在控制器中指定所有属性必须是有效的。让我们使用用户类重写前面的示例。

首先关于User类,关于属性的验证注释:

package models; public class User { @Required public String name; @Required @Min(0) public Integer age; }

然后是被修改的hello action,他是用@Valid注释指定所有用户对象的属性必须是有效的:

public static void hello(@Valid User user) { if(validation.hasErrors()) { params.flash(); // add http parameters to the flash scope validation.keep(); // keep the errors for the next request index(); } render(name, age); } 最后是修改后的表单:

#{ifErrors} <h1>Oops…</h1> #{/ifErrors} #{form @Application.hello()} <div> Name: <input type="text" name="user.name" value="${flash['user.name']}" /> <span class="error">#{error 'user.name' /}</span> </div> <div> Age: <input type="text" name="user.age" value="${flash['user.age']}" /> <span class="error">#{error 'user.age' /}</span> </div> <div> <input type="submit" value="Say hello" /> </div> #{/form}

内置的验证

play.data.validation包包含多个内置验证,可以在验证对象上使用,也可以在注释中使用。

自定义校验使用@CheckWith注释

在包play.data.validation中不能找到需要校验?编写你自己的校验使用@CheckWith注释绑定你自己的校验实现。

public class User { @Required @CheckWith(MyPasswordCheck.class) public String password; static class MyPasswordCheck extends Check { public boolean isSatisfied(Object user, Object password) { return notMatchPreviousPasswords(password); } } } 默认的校验错误信息key是validation.invalid,使用不同的键,调用 Check.setMessage使用一个消息key和消息参数。

static class MyPasswordCheck extends Check { public boolean isSatisfied(Object user, Object password) { final Date lastUsed = dateLastUsed(password); setMessage("validation.used", JavaExtensions.format(lastUsed)); return lastUsed == null; } } 消息查找总是以字段名作为第一个参数,和你的消息参数作为后续参数,因此,对于上面的例子,您可以定义如下消息:

validation.used = &{%1$s} already used on date %2$s user.password = Password

转载请注明原文地址: https://www.6miu.com/read-71151.html

最新回复(0)