JSR-303
어노테이션을 커스텀하여 검증해보자.message
, groups
, payload
메서드는 반드시 존재해야 한다.@Constraint
어노테이션에는 직접 생성할 ConstraintValidator
를 구현하는 Validator를 설정한다.@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AllowedValueValidator.class)
public @interface AllowedValue {
String[] values() default { "S", "M", "L" };
String message() default "{com.validator.constraints.AllowedValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
initialize
메서드에서는 초기화할 데이터가 필요한 경우 설정한다. 앞서 만든 어노테이션의 기본값으로 초기화했다.isValid
메서드에서는 실제 검증할 내용을 작성한다. 검증할 필드에 요청된 값이 values에 정의된 값 중에 존재하는지 확인했다.public class AllowedValueValidator implements ConstraintValidator<AllowedValue, String> {
private String[] values;
@Override
public void initialize(AllowedValue constraintAnnotation) {
this.values = constraintAnnotation.values();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return ArrayUtils.contains(values, value);
}
}
public class Clothing {
private String id;
private String name;
@AllowedValue
private String topSize;
@AllowedValue
private String bottomSize;
@AllowedValue(values = { "red", "blue" })
private String color;
}
@Valid
와 BindingResult
를 표기한다.@PostMapping("/clothing/update")
public void update(@Valid Clothing clothing, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldError();
throw new RuntimeException(fieldError.getDefaultMessage());
}
clothingManager.update(clothing);
}