http://yingzhuo.iteye.com/blog/1455438
SpringMVC杂记(五) JSR303数据验证
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 {};
- }
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());
- }
- }
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
- }
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) 效果图
