校验器的知识点大致可以分为三个部分
- 第一部分介绍与校验功能相关的类
- 第二部分介绍校验器实现方式。
- 第三部分介绍如何获取校验结果。
1、相关类
Spring中使用Validator接口实现校验功能,它只有两个方法
- Supports:用于判断校验器适用于哪些对象。
- Validate:实现校验功能的逻辑,第一个参数为校验对象,第二个参数为校验的结果。
在数据绑定的功能中,校验只是其中的子功能,Spring使用DataBinder类实现数据绑定功能,该对象也可以触发校验功能,它包含一个或多个校验器,有List<Validator>属性。
Spring还提供了ValidationUtils,它是一个工具类,提供一些常见的方法,例如对象是否为空,字符串属性是否为NULL或空白字符。
注:Validator和DataBinder都有自己的类结构。
2、实现方式
Spring支持三种校验方式。
- 第一种是JSR-303相关的注解API,具体参考Hibernate Validator。
- 第二种是代码方式,使用Validator或者是DataBinder的validate方法。
- 第三种是数据绑定过程中自动触发,例如请求参数转换为Controller方法中的参数。
2.1 HibernateValidator
待补充。
2.2 代码方式
代码方式的步骤如下,
- 第一步,编写自定义校验器,实现Validator接口。示例中校验用户的姓名和年龄
public class UserValidator implements Validator { public boolean supports(Class<?> clazz) { return User.class.isAssignableFrom(clazz); } public void validate(Object target, Errors errors) { // 判断姓名是否为空 ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "姓名不能为空"); // 转换为User对象 User user = (User) target; if (user.getAge() < 0) { errors.rejectValue("age", "年龄不能小于0"); } else if (user.getAge() > 100) { errors.rejectValue("age", "年龄不能大于100"); } } }
2.第二步,注册校验器,DataBinder方式是调用addValidator方法,Validator实现类方式是获取Validator实现类,可以直接new,也可以从IOC容器中获取。
调用Validator或者DataBinder的validate方法。代码如下:
-
DataBinder的validate方法,调用xxValidator的方法,添加,替换,删除校验器
/** * * @Title: testValidator * @Description: 测试校验器,调用DataBinder的validate方法 */ public static void testDataBinder() { ApplicationContext context = getContext(); // 获取User对象 User user = context.getBean("singleton_user", User.class); // DataBinder binder = new DataBinder(user); // 注册validator binder.addValidators(new UserValidator()); // 校验 binder.validate(); // 获取结果 BindingResult result = binder.getBindingResult(); // 获取 List<FieldError> errors = result.getFieldErrors(); // 输出User对象 System.out.println(user.toString()); // for (FieldError error : errors) { System.out.println(error.getField() + ": " + error.getCode()); } }
- Validator的validate方法,直接new,或者从IOC容器中获取。
/** * * @Title: testValidator * @Description: 测试校验器 */ public static void testValidator() { ApplicationContext context = getContext(); // 获取User对象 User user = context.getBean("singleton_user", User.class); // 创建UserValidator实例 UserValidator validator = new UserValidator(); // 创建Error对象 BindingResult result = new BeanPropertyBindingResult(user, "user"); // 校验 validator.validate(user, result); // 输出User对象 System.out.println(user.toString()); // 输出校验结果 System.out.println(result.getFieldErrorCount()); }
上述方式是直接new创建Validator,从IOC容器中获取Validator的方式,XML方式下配置validator接口的实现类,注解方式下在实现类上添加@Component注解。
2.3 数据绑定
在数据绑定的过程中,可以添加校验器,实现校验功能。最常见的数据绑定过程是请求的参数转换为Controller类中方法的参数,这个过程是自动的。不过可以修改,添加自定义的过滤器
@Controller public class MyController { @InitBinder protected void initBinder(WebDataBinder binder) { // 添加自定义校验器,在方法中添加Errors参数对象,获取校验结果 binder.addValidators(new XXValidator()); } // 请求参数转换为User对象, Errors对象获取校验结果 @GetMapping("/urlPath") public String test(User user, Errors errors) { return "您好 " + user.getName(); } }
3、获取校验结果
当为代码方式时,当使用DataBinder的validate方法之后,可以调用getBindingResult对象返回结果对象,调用BindingResult对象的相关API可以获取校验的结果,这个接口继承Errors接口。
当使用Validator时,在使用validate方法之前,必须先创建一个Errors的实现类,在示例中我使用的BeanPropertyBindingResult,然后把该对象作为参数传入到validate方法中,之后调用它的API获取校验的结果。
当为数据绑定方式时,在请求参数转换为对象方法参数的过程中,可以在方法中添加Errors参数,之后调用它的API获取校验的结果。