[譯]SpringMVC自定義驗證注解(SpringMVC custom validation annotations)


在基於SpringMVC框架的開發中,我們經常要對用戶提交的字段進行合法性驗證,比如整數類型的字段有個范圍約束,我們會用@Range(min=1, max=4)。在實際應用開發中,我們經常碰到一些自己業務的場景要自定義一些驗證規則,而這是標准的JSR-303Hibernate Validation所不具備的,所以我們就要根據JSR-303的規范來擴展我們自定義的驗證規則注釋.

假設我們現在有個接口要接收一個手機的字段, 它的約束規則是13位數字字符. 我們可以通過正則表達式完成: ^\d{13}$來驗證. 下面是個javabean代碼:

public class Person{
    @Phone
    private String phone;
}

我們再來看下@Phone的代碼.

@Documented
@Constraint(validatedBy = PhoneConstraintValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
	String message() default "{Phone}";
	Class<?>[] groups() default {};
	Class<? extends Payload>[] payload() default {};
}

這個注解類看起來復雜, 其實不然. 因為這基本上每個擴展驗證注解都必需定義的三個方法, 是規范定義的, 所以我們可以像個模板一樣copy過來改下. 這里要注意的是這個message方法, 定義了如果驗證出錯時要顯示的消息內容. 對於消息格式和規范, 可以使用標准的Spring Message Resource Bindle來, 可以參考這篇. 現在定義了注解, 正如你所料, 我們要定義下具體的業務規則:

public class PhoneConstraintValidator implements ConstraintValidator<Phone, String> {

	@Override
	public void initialize(Phone phone) { }

	@Override
	public boolean isValid(String phoneField, ConstraintValidatorContext cxt) {
		if(phoneField == null) {
			return false;
		}
		return phoneField.matches("^\d{13}$");
	}
}

所有驗證規則方法類都要實現ConstraintValidator<V,F>這個接口, 里面第一個方法initialize的參數是所關聯的注解對象, 所以這個方法里可以取出使用注解的地方傳進來的值, 后面一個例子會講到這一點. 第二個最核心的方法isValid第一個參數就是我們要驗證的字段值, 大家看下上面的代碼就知道怎樣使用了.

下面我們來看第二種形式的注解. 假如我們對用戶的生日字段進行驗證, 限制只滿足1989年出生的人。 如下:

public class Person {
	@Year(1989)
	private Date birthday;

    // getters setters ...

}

現在自定義驗證注解Year有要傳入一個參數, 用默認的value方法接收:

@Documented
@Constraint(validatedBy = YearConstraintValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Year {

	int value();

	String message() default "{Year}";

	Class<?>[] groups() default {};

	Class<? extends Payload>[] payload() default {};

}

還是要上面的一樣, 要定義一個規則約束描述類:

public class YearConstraintValidator implements ConstraintValidator<Year, Date> {

	private int annotationYear;

	@Override
	public void initialize(Year year) {
		this.annotationYear = year.value();
	}

	@Override
	public boolean isValid(Date target, ConstraintValidatorContext cxt) {
		if(target == null) {
			return true;
		}
		Calendar c = Calendar.getInstance();
		c.setTime(target);
		int fieldYear = c.get(Calendar.YEAR);
		return fieldYear == annotationYear;
	}

}

可以看到initiallize方法中可以接收關聯的注解Year, 這里可以取出里面的參數信息用於約束規則方法調用.

原文: http://www.javacodegeeks.com/2013/07/spring-mvc-custom-validation-annotations.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM