Validation의 메세지 처리는 생각보다 쉽지않다.
다음과 같이 작성된 Validation message는 서버에서만 확인 가능하다.
하지만 유효성 검사라는 것은 클라이언트에게 보여줘야 의미가 있지 서버에서 확인하는 것은 별로 의미가 없다.
@Getter
public class SpotStayListReqDto {
@NotNull(message = "spotId가 비어 있습니다.")
private Integer spotId;
@NotEmpty(message = "checkInDate가 비어 있습니다.")
@Size(min = 8, max = 8, message = "yyyyMMdd 형식으로 작성 바랍니다.")
private String checkInDate;
@NotEmpty(message = "checkOutDate가 비어 있습니다.")
@Size(min = 8, max = 8, message = "yyyyMMdd 형식으로 작성 바랍니다.")
private String checkOutDate;
private Integer roomCnt;
public SpotStayListReqDto(Integer spotId, String checkInDate, String checkOutDate, Integer roomCnt) {
this.spotId = spotId;
this.checkInDate = checkInDate;
this.checkOutDate = checkOutDate;
this.roomCnt = roomCnt;
}
}
아무리 검색을 해 보아도 Controller 딴에서 BindResult 변수를 통해 직접 맵핑하는 방식밖에 나오지 않아 절망하던 중 ControllerAdvice에서 정답을 찾았다.
유효성 검사 실패시 Spring Boot는 BindException을 터트리는데 이 예외가 BindResult 정보를 가지고 있어서 Advice로 추가 작업을 해주었다.
사용할 정보를 debug 모드로 하나씩 뒤져서 쓰다보니 코드가 살짝 지져분 해졌지만 결과에 매우 만족한다.
@RestControllerAdvice
public class ExceptionAdvice extends RuntimeException {
@ExceptionHandler(BindException.class)
public ResponseEntity<CommonResDto<List<String>>> handleBindException(BindException e) {
List<String> data = new ArrayList<>();
for (ObjectError error : e.getBindingResult().getAllErrors()) {
data.add(((DefaultMessageSourceResolvable) Objects.requireNonNull(error.getArguments())[0]).getDefaultMessage()
+ " : " + error.getDefaultMessage());
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CommonResDto.<List<String>>builder()
.code(ResponseCode.RESPONSE_0003.getCode())
.message(ResponseCode.RESPONSE_0003.getDefaultMessage()) // 파라미터 유효성 검사 실패!
.data(data)
.build());
}
}
'JAVA > Spring Boot' 카테고리의 다른 글
Join을 Map으로 최적화 (0) | 2023.02.23 |
---|---|
JPA) [수정]@DynamicUpdate, @DynamicInsert (0) | 2023.02.07 |
Spring Boot, Gradle 멀티 모듈 프로젝트 실전 예제 (0) | 2022.12.28 |
jwt 정리 잘 된 블로그 메모 (0) | 2022.07.13 |
JPA) N+1문제 (0) | 2022.06.20 |