やること
2項目間の値の一致チェックを行うバリデーションクラスを作成する。
はじめに
バリデーションを実装する場合は、
- バリデーションの対象に宣言する「アノテーション」
- 「アノテーション」に対してのチェック処理を行う「バリデータ」が必要。
アノテーション
CompareEquals.java
/**
* 2項目の値の一致チェックを行う。
*/
@Constraint(validatedBy = {CompareEqualsValidator.class})
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CompareEquals {
// バリデーションを実装する際の必須定義。
Class<?>[]groups() default {};
Class<? extends Payload>[] payload() default {};
String value1();
String value2();
String message();
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
CompareEquals[] values();
}
}
- @Constraint(validatedBy = {CompareEqualsValidator.class})でバリデータクラスを指定する。
- groups, payloadは必須項目。省略した場合は、下記例外が発生する。
javax.validation.ConstraintDefinitionException: HV000074: com.example.demo.com.annotation.CompareValue contains Constraint annotation, but does not contain a payload parameter.
バリデータクラス
CompareEqualsValidator
/**
* 2つのパラメタの一致判定を行う。
*/
public class CompareEqualsValidator implements ConstraintValidator<CompareEquals, Object> {
private String value1;
private String value2;
private String message;
/**
* 初期化処理
*/
@Override
public void initialize(CompareEquals annotation) {
// アノテーションの引数情報を設定する。
this.value1 = annotation.value1();
this.value2 = annotation.value2();
this.message = annotation.message();
}
/**
* 比較処理
*/
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
// 2つの値を取得して比較する。
BeanWrapper beanWrapper = new BeanWrapperImpl(value);
Object value1 = beanWrapper.getPropertyValue(this.value1);
Object value2 = beanWrapper.getPropertyValue(this.value2);
// 比較処理
// 同値でも型が違う場合はfalseを返却する。
boolean matched = ObjectUtils.nullSafeEquals(value1, value2);
if (matched) {
return true;
}
// メッセージを設定する。
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addPropertyNode(this.value1).addConstraintViolation();
return false;
}
}
- ObjectUtils.nullSafeEqualsはSpringのUtilityクラス
- isValidの引数valueにはFormクラスが渡される。
- beanWrapper.getPropertyValue()で誤ったフィールド名を渡した場合は下記例外が発生する。
org.springframework.beans.NotReadablePropertyException: Invalid property 'aaa' of bean class [com.example.demo.app.form.TestForm]: Bean property 'aaa' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?