日期:2014-05-16  浏览次数:20483 次

SpringMVC杂记(五) JSR303数据验证
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 {};
}

  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">
	<p