Spring有校验框架可以用来校验参数,模型的属性
如果不用注解的方式,那么典型的校验,应该是在方法体内创建一个Validator的实例,然后让它来校验某参数,如下所示:
- @ActionMapping(params="action=doSomething")
- public void doSomething(@ModelAttribute SomeObject someObject,
- BindingResult bindingResult) {
- Validator validator = new SomeValidator();
- validator.validate(someObject, bindingResult);
- if(!bindingResult.hasErrors()) {
- ...
- } else {
- ...
- }
- }
-----
如果用注解的方式,那么只要在方法参数前面加上@Valid就可以
- @ActionMapping(params="myaction=addBook")
- public void addBook(
- @Valid @ModelAttribute(value="book")Book book,
- BindingResult bindingResult,...) {
- if(!bindingResult.hasErrors()) {
- bookService.addBook(book);
- response.setRenderParameter("myaction", "books");
- sessionStatus.setComplete();
- } else {
- response.setRenderParameter("myaction", "addBook");
- }
- }
注意,如果使用@Valid,则必须声明校验器并且进行于请求参数绑定,绑定方法有两种,一种是xml配置,一种是用@InitBinder声明,两种的本质都是用于绑定校验器对象到webBindingInitilizer对象中
如果用xml的方式,那么配置如下:(使用场合:一个校验器适用于所有的控制器
- <beans...>
- ...
- <bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- <property name="webBindingInitializer">
- <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
- <property name="validator" ref="myValidator" />
- </bean>
- </bean>
- <bean id="myValidator" class="..." />
- ...
- </beans>
如果用@InitBinder ,那么代码如下:(使用场合:一个校验器只适用于一个控制器
- public class SomeController {
- ...
- @Autowired
- @Qualifier("myValidator")
- private Validator myValidator;
- ...
- @InitBinder("someObject")
- public void initBinder(WebDataBinder binder) {
- binder.setValidator(myValidator);
- }
- ...
- }
----
定义校验逻辑:
光会在代码中为字段配置其使用的校验器还远远不够,因为校验器的校验逻辑还需要我们程序员自己去定制:
定制校验逻辑也有两种方法:
方法1: 自定义校验器类让其实现Validator接口并且实现supports和validate方法,这种方式很直观,因为要校验domain对象,所以我定义这个domain对象的校验逻辑
- public class AddBookValidator implements Validator {
- @Autowired
- @Qualifier("myBookService")
- private BookService bookService;
- public boolean supports(Class<?> klass) {
- return Book.class.isAssignableFrom(klass);
- }
- public void validate(Object target, Errors errors) {
- Book book = (Book)target;
- ValidationUtils.rejectIfEmptyOrWhitespace(errors,
- "name", "name.field.required");
- ValidationUtils.rejectIfEmptyOrWhitespace(errors,
- "author", "author.field.required");
- String name = book.getName();
- if(name.length() >10 || name.length() < 3) {
- errors.reject("name", "name.field.max.min.size");
- }
- if(bookService.isUnique(book.getIsbnNumber())) {
- errors.reject("isbnNumber", "isbnNumber.field.unique.constraint");
- }
- }
- }
方法2: 直接在领域对象本身中用某些注解来定制校验规则:
- public class Book {
- @NotEmpty
- @Size(max=100, min=10)
- private String name;
- @NotEmpty
- private String author;
- @Unique
- private Long isbnNumber;
- public Book(String name, String author, long isbnNumber) {
- this.name = name;
- this.author = author;
- this.isbnNumber = isbnNumber;
- }
- ...
- }
----
如何在Spring中启用校验框架?
只要在Spring配置文件中指定其类的实例为LocalValidatorFactoryBean,你还可以为他指定国际化资源来显示校验结果:
- <!-- Validation -->
- <bean id="validator"
- class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
- <property name="validationMessageSource" ref="messageSource" />
- </bean>