Request 시 String 필드가 특정 String만 받도록 검증하려고 할 때 다음과 같이 구현
@EnumValidator라는 Custom Annotation을 만들어서 target Enum에서 정의한 값들만 해당 필드에 받을 수 있도록 검증
EnumValidator (Annotation)
@Documented
@Constraint(validatedBy = EnumValidatorImpl.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@NotNull(message = "Value cannot be null")
@ReportAsSingleViolation
public @interface EnumValidator {
Class<? extends Enum<?>> targetEnum();
String message() default "Value is not valid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
EnumValidatorImpl
public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, String> {
Set<String> valueSet = null;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return valueSet.contains(value.toUpperCase());
}
@Override
public void initialize(EnumValidator constraintAnnotation) {
valueSet = new HashSet<>();
Class<? extends Enum<?>> enumClass = constraintAnnotation.targetEnum();
@SuppressWarnings("rawtypes")
Enum[] enumValArr = enumClass.getEnumConstants();
for (@SuppressWarnings("rawtypes") Enum enumVal : enumValArr) {
valueSet.add(enumVal.toString().toUpperCase());
}
}
}
Request VO에 @EnumValidator 적용
1. Target Enum 정의
public enum AuthGroup {
ADMIN,
USER
}
2. VO에 적용
@Data
public class TestVO {
private String name;
private int age;
@EnumValidator(
targetEnum = AuthGroup.class,
message = "authGroup can be either ADMIN or USER"
)
private String authGroup;
}
Test
- @Validated annotation 적용
@PostMapping("/test")
public CommonResponse<TestVO> test(@RequestBody @Validated TestVO vo) {
...
}
- Request (IntelliJ Http Reqeust 사용함)
###
//@no-log
POST http://localhost:5423/test
Content-Type: application/json
{
"name": "name",
"age": 27,
"authGroup": "GUEST"
}
// Response
{
"timestamp": "2023-11-09T05:02:17.477+00:00",
"status": 400,
"error": "Bad Request",
"path": "/test"
}
- Error Log
2023-11-09 14:02:17.477 WARN 18195 --- [nio-5423-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.example.demo.vo.CommonResponse<com.example.demo.vo.TestVO> com.example.demo.ctl.DemoController.test(com.example.demo.vo.TestVO): [Field error in object 'testVO' on field 'authGroup': rejected value [GUEST]; codes [EnumValidator.testVO.authGroup,EnumValidator.authGroup,EnumValidator.java.lang.String,EnumValidator]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [testVO.authGroup,authGroup]; arguments []; default message [authGroup],class com.example.demo.validation.AuthGroup]; default message [authGroup can be either ADMIN or USER]] ]
@EnumValidator에서 입력한 message가 default message에 출력되는 것 확인
참고
Java String validation using enum values and annotation
'Spring' 카테고리의 다른 글
Spring JPA hibernate.ddl-auto 정리 (0) | 2023.12.04 |
---|---|
Spring @RestControllerAdvice 적용 (0) | 2023.11.09 |
Spring Boot & Thymeleaf 토이 프로젝트 [Course Registration System] (2) | 2022.04.01 |
Spring JUnit5 Sql script로 테스트 데이터 불러오기 (0) | 2022.03.17 |
[Spring][Error] Spring Security 적용할 때 circular reference, dependency가 cycle 형성하는 것 해결하기 (2) | 2022.03.14 |
댓글