SignupRequestDto
@Getter
@NoArgsConstructor
public class SignupRequestDto {
@NotBlank
@Size(min = 4,max = 10, message ="작성자명은 4자 이상 10자 이하만 가능합니다.")
@Pattern(regexp = "^[a-z0-9]*$", message = "작성자명은 알파벳 소문자, 숫자만 사용 가능합니다.")
private String username;
@NotBlank
@Size(min = 8,max = 15, message ="비밀번호는 8자 이상 15자 이하만 가능합니다.")
@Pattern(regexp = "^[a-zA-Z_0-9]*$", message = "비밀번호는 알파벳 대소문자, 숫자만 사용 가능합니다.")
private String password;
private boolean admin = false; // 디폴트 값은 false. 관리자 권한일 경우 true 로 변한다
private String adminToken = "";
}
requestDto 에서 유효성 검사를 실시했다.
그러나 body 에는 유효성 검사 실패 메시지가 뜨지 않았는데, 이는 @RestControllerAdvice 를 이용한 전역 예외 처리가 있었기 때문이다.
service 단에서 유효성 검사 로직과 예외 메시지를 처리해봤으나, 정상적으로 반환되지 않았다.
유효성 검사에 관한 예외 처리 또한 @RestControllerAdvice 를 이용해야 했기 때문이다.
GlobalExceptionHandler 는 ResponseEntityExceptionHandler 를 상속받는다.
ResponseEntityExceptionHandler 를 들어가 확인해보니, MethodArgumentNotValidException 클래스가 사용될 수 있다는 것을 확인 할 수 있었다.
GlobalExceptionHandler
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
// 유효성 검사
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
BindingResult bindingResult = ex.getBindingResult(); // 1.
StringBuilder stringBuilder = new StringBuilder();
for (FieldError fieldError : bindingResult.getFieldErrors()) { // 2.
stringBuilder.append(fieldError.getDefaultMessage()); // 3.
stringBuilder.append(" ");
}
final ErrorResponse response = new ErrorResponse(ErrorCode.INVALID_FORMAT.getHttpStatus().value(), String.valueOf(stringBuilder)); // 4.
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
...
}
1.
2.
3.
4.
ErrorCode.INVALID_FORMAT.getHttpStatus().value() 를 통해, INVALID_FORMAT 에러의 HTTP 상태 코드를 받을 수 있다.
public enum ErrorCode {
INVALID_FORMAT(HttpStatus.BAD_REQUEST, "올바르지 않은 유형"),
...
String.valueOf(stringBuilder) 를 통해, stringBuilder 에 담아둔 에러 메시지를 String 타입으로 변환한다.
왜냐면 ErrorResponse 클래스에서는 ErrorCode 클래스에 선언된 String message 를 받아오기 때문이다.
참고: [Java] Global Exception 이해하고 구성하기 : Controller Exception
참고: [Spring] @RestControllerAdvice를 이용한 Spring 예외 처리 방법 - (2/2)
참고: [예외처리] @Valid 예외처리에 사용되는 BindingResult 객체는 무엇일까?