清新素雅的乌镇让人向往,代码中的世界是不是也是如此呢?老牌参数验证方式,JSR303校验 你值得拥有!❤️
介绍
JSR303是Java为Bean数据合法性校验提供的标准框架- 通过在Bean属性上标注类似于
@NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证@Null:被注释的元素必须为null@NotNull:被注释的元素必须为不能为null@AssertTrue:被注释的元素必须为true@AssertFalse:被注释的元素必须为false@Min(value):被注释的元素必须是一个数字,值必须必须大于等于value@Max(value):被注释的元素必须是一个数字,值必须必须小于等于value@DecimalMin(value):被注释的元素必须是一个数字,值必须必须大于等于value@DecimalMax(value):被注释的元素必须是一个数字,值必须必须小于等于value@Size(max, min):被注释的元素大小必须在指定的范围内@Digits(integer, fraction):被注释的元素必须是一个数字,值必须在可接收的范围内@Past:被注释的元素必须是一个过去的日期@Future:被注释的元素必须是一个将来的日期@Pattern:被注释的元素必须符合指定的正则表达式
SpringMVC数据校验
- Spring4.0拥有自己独立的数据校验框架,同时支持JSR303标准的校验框架
- Spring在进行数据绑定时,可同时调用校验框架完成数据的校验工作。在SpringMVC中,可直接通过注解驱动的方式进行数据校验
- Spring的
LocalValidatorFactoryBean既实现了Spring的Validator接口,也实现了JSR303的Validator接口,只要在Spring容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的Bean中 - Spring本身并没有提供JSR303的实现,所以必须手动引入JSR303的实现jar
<mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解即可让SpringMVC在完成数据绑定后执行数据校验的工作- 在已经该标注了JSR303注解的表单对象前标注一个
@Valid,SpringMVC框架在将请求参数绑定到该入参对象后,就会调用校验框架根据注解声明的校验规则实施校验 - SpringMVC是通过对处理方法签名的规约来保存校验结果的
- 前一个表单对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是
BindingResult或Errors类型 - 这两个类都在
org.springframework.validation包中
- 前一个表单对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是
上手操作
- 使用JSR303验证标准
- 加入
hibernate validator验证框架jar包 - springMvc 配置文件中添加
<mvc:annotation-driven/> - 需要在bean的属性上添加对应的注解
- 在目标方法bean类型的前面添加@Valid注解
- 验证出错转向页面
- 错误消息显示,将错误消息国际化
public class Car{
@NotNull
private Stirng name;
@Max(18)
private Integer age;
@Override
public String toString() {
return "Car{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
@RequestMapping("/testValidate")
public String testValidate(@Valid Car car, BindResult result,
Map<String, Object> map, HttpservletRequrst request, HttpServletResponse response){
response.setCharacterEncoding("utf-8");
System.out.println("car: "+car);
if(result.getErrorCount()>0){
System.out.println("出错了");
for(FieldError error: result.getFieldErrors()){
System.out.println(error.getField()+" : "+error.getDefaultMessage());
}
map.put("car", car);
return "/File1";
}
return "success";
}
- 加载国际化资源文件:
- 新建资源文件 ValidationMessages.properties
- key值为 NotEmpty.car.name格式(注解名.类名首字母小写.属性名)
- springMvc中配置
NotEmpty.car.name=名字得添上啊
Min.car.age=未满18岁不能进入
<!--springmvc中配置-->
<mvc:annotation-driven validator="validator"></mvc:annotation-driven>
<!--jsr303数据验证-->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!--hibernate校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<!--指定校验使用的资源文件,在文件中配置校验信息,如果不指定则默认使用classpath下的ValidationMessages.properties-->
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<!--配置国际化资源文件-->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:ValidationMessages</value>
</list>
</property>
<property name="fileEncodings" value="UTF-8" />
<property name="cacheSeconds" value="60" />
</bean>
<!--还可以这样因为mvc annotation driven 注解默认装配了LocalValidatorFactoryBean-->
<!--第二种配置方式-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="ValidationMessages"></property>
</bean>
- 每个属性在数据绑定和数据校验发生错误的时候,都会生成一个对应的FieldError对象
- 当一个属性校验失败后,校验框架会为该属性生成4个消息代码,这些代码以校验注解类名为前缀,结合
modleAttribute、属性名以及属性类名生成多个对应的消息代码例如User类的password属性标注了@Pattern注解,当该属性的值不满足校验规则的时候,会产生如下四个错误代码- Pattern.user.password
- Pattern.password
- Pattern.java.long.Stirng
- Pattern
- 当使用SpringMVC标签显示错误消息的时候,SpirngMVC会查看web上下文中是否装配了对应的国际化资源消息,如果没有,则显示默认的错误消息,否则使用国际化消息
自定义校验注解
- 新建一个注解
//其中的三个属性为校验所必须的三个属性。
//@constraint注解指示具体的校验类:
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {MyConstraintValidator.class})
public @interface Myconstraint{
String message() default "{javax.validation.constraints.NotNull.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public class MyConstraintValidator implements ConstrainValidator<Myconstraint, String>{
@Override
public void initialize(Myconstraint constraintAnnotation){
System.out.println("initialize...");
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context){
System.out.println(value);
String defaultConstraintMessageTemplate = context.getDefaultConstrainMessageTemplate();
System.out.println(defaultConstraintMessageTemplate);
return true;
}
}
- 校验类需要实现
ConstraintValidator接口,第一个泛型是自己新建的校验注解,第二个泛型是校验什么字段类型。 - 其中的
initialize方法不是在项目启动的时候调用,是在这个注解第一次使用的时候调用。isValid方法是具体的校验方法,返回true校验成功,返回false校验失败. - 这个方法上的第一个参数value:是校验字段的值,第二个参数是该校验注解注解信息。
- 使用的时候就在需要校验的字段上面添加
@Myconstraint注解