문제상황
Controller에서 @RequestBody에 @Valid를 사용 할 경우,
단일 Object 타입일 때는 Validator가 잘 동작하지만,
객체가 Collection 타입으로 감싸져 있을 경우에는 Validator가 동작을 하지 못했다.(예외를 내뱉지 않음)
아래는 문제가 되는 예시
@PostMapping("")
public Result doOrder(@RequestBody @Valid List<OrderRequest> order, Errors errors) {
return orderService.doOrder(order);
}
문제원인
에러가 나지 않는 이유는 @Valid는 JavaBeans에 적용되는데, List(컬렉션)는 JavaBeans 명세에 포함되지 않기 때문이다.
해결
Validation.buildDefaultValidatorFactory().getValidator()와 SpringValidatorAdapter를 이용하면 된다.
1. CustomValidator 를 만든다.
package com.kiosk.coffee.custom;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import javax.validation.Validation;
import java.util.Collection;
// Collection도 Validation 체크 가능하도록 Bean으로 등록
@Component
public class CustomCollectionValidator implements Validator {
private SpringValidatorAdapter validator;
public CustomCollectionValidator() {
this.validator = new SpringValidatorAdapter(
Validation.buildDefaultValidatorFactory().getValidator()
);
}
@Override
public boolean supports(Class<?> clazz) {
return true; // 모든 타입 true로 반환
}
@Override
public void validate(Object target, Errors errors) {
if(target instanceof Collection){
Collection collection = (Collection) target;
for (Object object : collection) {
validator.validate(object, errors);
}
} else {
validator.validate(target, errors);
}
}
}
2. controller에 생성자 주입 해주고, Dto가 컬렉션일 경우엔 validate(dto, errors) 메소드를 태워준다.
@Autowired
CustomCollectionValidator customCollectionValidator;
@PostMapping("")
public Result doOrder(@RequestBody @Valid List<OrderRequest> order, @ApiIgnore Errors errors) {
// 이거 추가 : 컬렉션 객체도 검증하도록!
customCollectionValidator.validate(order, errors);
return orderService.doOrder(order);
}
✏️✏️이제 @RequestBody로 받는 컬렉션 내부의 모든 객체들에 대해서 유효성 검사를 하게된다.
'Back > Spring Boot' 카테고리의 다른 글
[SpringBoot] war로 배포하기, 외장 톰캣 구동 (+Trouble Shooting) (1) | 2023.10.11 |
---|---|
[Gradle] biuld.gradle 살펴보기 (0) | 2023.09.05 |
[Spring Boot] .jar 배포 후 resources 파일 경로 찾기 (2) | 2022.06.10 |
[SpringBoot] @Valid 어노테이션으로 validation 유효성 검사하기 (0) | 2022.02.08 |
[Spring Boot, IntelliJ] 인텔리제이 서버 재시작 없이 정적 리소스 리로드하기 (4) | 2022.02.04 |
댓글