SpringMVC杂记(五) JSR303数据验证 自定义验证规则

http://yingzhuo.iteye.com/blog/1455438



SpringMVC杂记(五) JSR303数据验证

1) 首先JSR303的实现必须加入CLASSPATH

Xml代码 复制代码 收藏代码
  1. <dependency>
  2. <groupId>org.hibernate</groupId>
  3. <artifactId>hibernate-validator</artifactId>
  4. <version>4.2.0.Final</version>
  5. </dependency>


2) SpringMVC 中的配置
Xml代码 复制代码 收藏代码
  1. <mvc:annotation-driven validator="validator"/>
  2. <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />


3) 关于JSR303给出的默认标注和Hibernate可以参考 hibernate-validator官方文档
我的 另一篇博客也简要介绍了一下


4) 自己实现验证规则
4.1 自定义元注释
Java代码 复制代码 收藏代码
  1. package com.wicresoft.jpo.demo.validator;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. import javax.validation.Constraint;
  8. import javax.validation.Payload;
  9. @Documented
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD})
  12. @Constraint(validatedBy = {BetweenImplForDate.class})
  13. public @interface Between {
  14. public String message();
  15. public String startDate();
  16. public String endDate();
  17. public String format() default "yyyy-MM-dd";
  18. public Class<?>[] groups() default {};
  19. Class<? extends Payload>[] payload() default {};
  20. }
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 验证器实现类
Java代码 复制代码 收藏代码
  1. package com.wicresoft.jpo.demo.validator;
  2. import java.text.DateFormat;
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import javax.validation.ConstraintValidator;
  7. import javax.validation.ConstraintValidatorContext;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. public class BetweenImplForDate implements ConstraintValidator<Between, Date> {
  11. private static final Logger LOGGER = LoggerFactory.getLogger(BetweenImplForDate.class);
  12. private Date startDate;
  13. private Date endDate;
  14. private DateFormat dateFormat;
  15. public void initialize(Between annotation) {
  16. this.dateFormat = new SimpleDateFormat(annotation.format());
  17. try {
  18. this.startDate = dateFormat.parse(annotation.startDate());
  19. this.endDate = dateFormat.parse(annotation.endDate());
  20. } catch (ParseException e) {
  21. throw new IllegalArgumentException(e.getMessage(), e);
  22. }
  23. }
  24. public boolean isValid(Date value, ConstraintValidatorContext context) {
  25. LOGGER.debug("value = {}", dateFormat.format(value));
  26. return (startDate.getTime() <= value.getTime()) && (value.getTime() < endDate.getTime());
  27. }
  28. }
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配置文件改成如下。
Properties代码 复制代码 收藏代码
  1. v.login.birthday=生日不合法,生日应在{startDate}与{endDate}之间。

Xml代码 复制代码 收藏代码
  1. <mvc:annotation-driven conversion-service="conversion-service" validator="validator">
  2. <mvc:message-converters register-defaults="false">
  3. <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
  4. <bean class="org.springframework.http.converter.FormHttpMessageConverter" />
  5. <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
  6. <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
  7. <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
  8. <bean class="com.wicresoft.jpo.demo.http.converter.UTF8StringHttpMessageConverter" />
  9. </mvc:message-converters>
  10. </mvc:annotation-driven>
  11. <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
  12. <property name="validationMessageSource" ref="messageSource" />
  13. </bean>
  14. <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  15. <property name="defaultEncoding" value="UTF-8" />
  16. <property name="basenames">
  17. <list>
  18. <value>classpath:com/wicresoft/jpo/demo/i18n/v</value>
  19. </list>
  20. </property>
  21. </bean>

Jsp代码 复制代码 收藏代码
  1. ...
  2. <tr>
  3. <td>生日</td>
  4. <td><form:input path="birthday" /></td>
  5. <td><form:errors path="birthday" /></td>
  6. </tr>
  7. ...


5) 使用标注
Java代码 复制代码 收藏代码
  1. public class UserRegistForm implements java.io.Serializable {
  2. private static final long serialVersionUID = -5471272011192637665L;
  3. private String username;
  4. private String password;
  5. private String sex;
  6. @DateTimeFormat(pattern = "yyyy-MM-dd")
  7. // message 就是国际化文件中的key
  8. @Between(startDate = "1930-01-01", endDate = "2012-12-31", message = "{v.login.birthday}")
  9. private Date birthday;
  10. private String phoneNumber;
  11. private String emailAddress;
  12. private List<String> interests = new ArrayList<String>();
  13. // getter and setter
  14. }
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) 效果图

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值