이번 강의에서는 Authorization 헤더가 아예 전달되지 않았을 때
왜 @NotBlank 검증 에러가 아니라 MissingRequestHeaderException 이 발생하는지,
그리고 이를 GlobalExceptionHandler에서 직접 처리하는 이유를 정리했다.
Postman에서 인증이 필요한 API 요청을 보낼 때
Authorization 헤더를 아예 제거하고 요청을 보내면 다음과 같은 에러가 발생했다.
{
"status": 400,
"error": "Bad Request",
"message": "Required request header 'Authorization' is not present"
}
처음에는 이렇게 생각했다.
"Authorization에
@NotBlank를 붙였으니까
NotBlank 검증 오류가 떠야 하는 거 아닌가?"
하지만 실제로는 전혀 다른 예외가 발생했다.
핵심은 Spring MVC의 요청 처리 순서에 있다.
@RequestHeader("Authorization") 확인즉,
@NotBlankMissingRequestHeaderException그래서 이 상황에서는 @NotBlank가 동작할 기회조차 없다.
| 상황 | 발생 예외 |
|---|---|
| Authorization 헤더 없음 | MissingRequestHeaderException |
| Authorization: "" | @NotBlank 검증 오류 |
| Authorization: "Bearer xxx" | 정상 |
이 예외를 그대로 두면 Spring 기본 에러 응답(JSON 구조가 제각각)이 내려간다.
그래서 우리 프로젝트의 RsData 포맷에 맞게 직접 처리했다.
@ExceptionHandler(MissingRequestHeaderException.class)
public ResponseEntity<RsData<Void>> handle(MissingRequestHeaderException ex) {
return new ResponseEntity<>(
new RsData<>(
"400-1",
"%s-%s-%s".formatted(
ex.getHeaderName(),
"NotBlank",
ex.getLocalizedMessage()
)
),
BAD_REQUEST
);
}
@ExceptionHandler(MissingRequestHeaderException.class)ex.getHeaderName()ex.getHeaderName()
"Authorization""NotBlank" 를 문자열로 넣은 이유ex.getLocalizedMessage() 의 역할ex.getLocalizedMessage()
👉 예외 객체가 기본적으로 가지고 있는 "사람용 설명 문장"
반환되는 값 예시:
Required request header 'Authorization' is not present
중요한 점은,
즉,
에러 메시지가 줄어든 게 아니라 정제된 것이다.
Authorization-NotBlank-Required request header 'Authorization' is not present
이 메시지 하나로 다음을 모두 전달한다.
@RequestHeader가 없으면 검증 이전에 예외가 터진다@NotBlank는 값이 존재할 때만 의미가 있다ex.getLocalizedMessage()는이번 강의는
Spring의 요청 바인딩 순서를 이해했는지가 핵심 포인트였다.