やりたいこと
リクエストクラスでは以下@NotNull
や@Size
のような
@
のついたアノテーションで入力チェックをすることができる。
用意されているアノテーションは一つの項目のみしかチェックを行うことができない。
複数の項目を検証するアノテーションが欲しいため、独自に作成したアノテーションで入力チェックを行いたい。
リクエストクラス
.Java
public class SampleRequest {
// nullは不可
@NotNull
private Integer id;
// 1〜50文字
@Size(min = 1, max = 50)
private String name;
private String name1;
private String name2;
private String name3;
public Sample convert() {
Sample sample = new Sample();
sample.setId(id);
sample.setName(name);
sample.setName(name1);
sample.setName(name2);
sample.setName(name3);
return sample;
}
}
今回やること
上記のリクエストクラスで、「name1, name2, name3のうち2つ以上の入力が必要」
という入力チェックを行うアノテーションを作成する。
1. 入力チェック内容を記載したクラスを作る
どんな入力チェックを行いたいかを記載する。
.Java
package test.pj.web.validation;
import java.util.ArrayList;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
// ConstraintValidator の実装クラスとして作成する
// <>内の引数1つ目は下記2のアノテーションクラス名
public class SampleAnnotationValidation
implements ConstraintValidator<SampleAnnotation, Object> {
// バリデーション対象の変数の値を入れる
private String[] fields;
// アノテーションクラス(下記2)で設定しているエラーメッセージが入る
private String message;
/**
* 初期化処理
* ()内のクラスは下記2のアノテーションクラス
*/
public void initialize(SampleAnnotation annotation) {
this.fields = annotation.fields();
this.message = annotation.message();
}
/**
* 自分でバリデーション内容を設定する
*/
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
BeanWrapper beanWrapper = new BeanWrapperImpl(value);
// 入力されている回数をカウントする変数を作成
Integer idCount = 0;
for (String string : fields) {
// 以下で、fieldValueに、validation対象の各値(今回の場合、name1, name2, name3)が入る
Object value = beanWrapper.getPropertyValue(string);
// 入力がある場合、入力カウントに1を足しておく
if (value != "") {
idCount += 1;
}
}
// 入力数が2以上のときはtrueを返す
if (idCount >= 2)) {
return true;
}
// それ以外はfalseを返し、messageを出す
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addPropertyNode(fields[0])
.addConstraintViolation();
return false;
}
}
2. アノテーションクラスを作る
@hogehoge
の名前の部分を作る
.Java
package test.pj.web.validation;
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
// 1で記載した入力チェック内容を記載したクラスをかく
@Constraint(validatedBy = {SampleAnnotationValidation.class})
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
// クラス名には、アノテーション名として使いたい名前をつける
public @interface SampleAnnotation {
// 入力チェック不可だった場合に、表示するエラーメッセージ
String message() default "name1, name2, name3のいずれか2つ以上を入力してください。";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
SampleAnnotation[] value();
}
// チェックする値を格納
String[] fields();
}
3.リクエストクラスに自作したアノテーションをつける
.Java
package test.pj.web.validation;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import test.pj.web.validation.SampleAnnotation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
// 2で作成したアノテーション名と、入力チェックを行いたい項目を入れる
@SampleAnnotation(fields = {"name1", "name2", "name3"})
@AllArgsConstructor
@NoArgsConstructor
public class SampleRequest {
// nullは不可
@NotNull
private Integer id;
// blankは不可、1〜50文字
@NotBlank
@Size(min = 1, max = 50)
private String name;
private String name1;
private String name2;
private String name3;
public Sample convert() {
Sample sample = new Sample();
sample.setId(id);
sample.setName(name);
sample.setName(name1);
sample.setName(name2);
sample.setName(name3);
return sample;
}
}