1) 首先JSR303的实现必须加入CLASSPATH
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.2.0.Final</version> </dependency>
2) SpringMVC 中的配置
<mvc:annotation-driven validator="validator"/> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
3) 关于JSR303给出的默认标注和Hibernate可以参考 hibernate-validator官方文档
我的 另一篇博客也简要介绍了一下
4) 自己实现验证规则
4.1 自定义元注释
package com.wicresoft.jpo.demo.validator; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD}) @Constraint(validatedBy = {BetweenImplForDate.class}) public @interface Between { public String message(); public String startDate(); public String endDate(); public String format() default "yyyy-MM-dd"; public Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
4.2 验证器实现类
package com.wicresoft.jpo.demo.validator; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BetweenImplForDate implements ConstraintValidator<Between, Date> { private static final Logger LOGGER = LoggerFactory.getLogger(BetweenImplForDate.class); private Date startDate; private Date endDate; private DateFormat dateFormat; public void initialize(Between annotation) { this.dateFormat = new SimpleDateFormat(annotation.format()); try { this.startDate = dateFormat.parse(annotation.startDate()); this.endDate = dateFormat.parse(annotation.endDate()); } catch (ParseException e) { throw new IllegalArgumentException(e.getMessage(), e); } } public boolean isValid(Date value, ConstraintValidatorContext context) { LOGGER.debug("value = {}", dateFormat.format(value)); return (startDate.getTime() <= value.getTime()) && (value.getTime() < endDate.getTime()); } }
4.3 添加国际化支持,让错误信息配置在i18n文件里。SpringMVC配置文件改成如下。
v.login.birthday=生日不合法,生日应在{startDate}与{endDate}之间。
<mvc:annotation-driven conversion-service="conversion-service" validator="validator"> <mvc:message-converters register-defaults="false"> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> <bean class="org.springframework.http.converter.FormHttpMessageConverter" /> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" /> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> <bean class="com.wicresoft.jpo.demo.http.converter.UTF8StringHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="validationMessageSource" ref="messageSource" /> </bean> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="defaultEncoding" value="UTF-8" /> <property name="basenames"> <list> <value>classpath:com/wicresoft/jpo/demo/i18n/v</value> </list> </property> </bean>
... <tr> <td>生日</td> <td><form:input path="birthday" /></td> <td><form:errors path="birthday" /></td> </tr> ...
5) 使用标注
public class UserRegistForm implements java.io.Serializable { private static final long serialVersionUID = -5471272011192637665L; private String username; private String password; private String sex; @DateTimeFormat(pattern = "yyyy-MM-dd") // message 就是国际化文件中的key @Between(startDate = "1930-01-01", endDate = "2012-12-31", message = "{v.login.birthday}") private Date birthday; private String phoneNumber; private String emailAddress; private List<String> interests = new ArrayList<String>(); // getter and setter }
6) 效果图