2025. 2. 28. 01:48ㆍSpring Framework/Web on Servlet Stack
Spring MVC에서 예외(Exception)가 발생하면 DispatcherServlet은 여러 단계의 예외 처리 메커니즘을 통해 적절한 응답을 생성합니다.
이를 위해 HandlerExceptionResolver 인터페이스를 구현한 다양한 예외 처리 전략이 존재합니다.
1. Spring MVC에서 예외가 발생하는 시점
예외는 다음과 같은 경우에 발생할 수 있습니다.
1️⃣ 요청 매핑(Request Mapping) 과정에서 예외 발생
- 존재하지 않는 URL을 호출한 경우 (
NoHandlerFoundException
) - 요청이 유효하지 않은 경우 (
HttpRequestMethodNotSupportedException
)
2️⃣ 컨트롤러(Controller) 내부에서 예외 발생
@RequestMapping
이 있는 메서드에서 예외 발생- 예를 들어, 데이터베이스 조회 시
EntityNotFoundException
발생
3️⃣ 응답 변환 과정에서 예외 발생
- JSON 변환 중
HttpMessageNotWritableException
발생
4️⃣ 필터(Filter) 또는 인터셉터(Interceptor)에서 예외 발생
📌 이러한 예외가 발생하면 DispatcherServlet은 HandlerExceptionResolver
체인을 실행하여 적절한 처리를 시도합니다.
2. HandlerExceptionResolver 종류
Spring MVC는 여러 가지 예외 처리 전략을 제공합니다.
📌 HandlerExceptionResolver 구현체
예외 처리기 | 설명 |
---|---|
SimpleMappingExceptionResolver | 예외 클래스와 특정 에러 페이지(View)를 매핑 |
DefaultHandlerExceptionResolver | Spring MVC에서 발생하는 예외를 HTTP 상태 코드로 매핑 |
ResponseStatusExceptionResolver | @ResponseStatus 어노테이션이 있는 예외를 HTTP 상태 코드로 매핑 |
ExceptionHandlerExceptionResolver | @ExceptionHandler 메서드를 실행하여 예외 처리 |
📌 예외 처리기들은 순차적으로 실행되며, 첫 번째로 예외를 처리할 수 있는 Resolver가 실행됨.
3. 개별 예외 처리기(HandlerExceptionResolver) 설명
✅ 1. SimpleMappingExceptionResolver (예외 ↔ 에러 페이지 매핑)
디폴트로 예외 클래스와 특정 뷰(View)를 연결하는 방식입니다.
일반적으로 JSP 같은 HTML 기반 뷰를 반환하는 경우 유용합니다.
📌 설정 예제 (Java 기반)
@Bean
public SimpleMappingExceptionResolver exceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.put("com.example.exception.UserNotFoundException", "error/userNotFound");
mappings.put("java.lang.Exception", "error/generalError");
resolver.setExceptionMappings(mappings);
return resolver;
}
➡ 특정 예외(UserNotFoundException
) 발생 시 "error/userNotFound.jsp"
페이지로 이동.
✅ 2. DefaultHandlerExceptionResolver (Spring MVC 기본 예외 변환)
Spring MVC에서 발생하는 예외를 자동으로 HTTP 상태 코드로 변환합니다.
예를 들어, HttpRequestMethodNotSupportedException
이 발생하면 405 Method Not Allowed를 반환합니다.
📌 예제: DefaultHandlerExceptionResolver의 디폴트 동작
예외: HttpRequestMethodNotSupportedException
응답: HTTP 405 Method Not Allowed
➡ 별도의 설정 없이 자동 적용되며, 디폴트로 활성화되어 있음.
✅ 3. ResponseStatusExceptionResolver (@ResponseStatus
사용)
특정 예외 발생 시 HTTP 상태 코드와 메시지를 직접 지정할 수 있습니다.
📌 예제: @ResponseStatus
로 예외 매핑
@ResponseStatus(HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
}
➡ UserNotFoundException
이 발생하면 HTTP 404 Not Found 응답 반환.
✅ 4. ExceptionHandlerExceptionResolver (@ExceptionHandler
사용)
컨트롤러 내부에서 @ExceptionHandler
를 사용하여 예외를 처리할 수 있습니다.@ControllerAdvice
를 사용하면 애플리케이션 전역(Global)에서 예외를 처리할 수도 있습니다.
📌 예제: @ExceptionHandler
를 사용한 예외 처리
@RestController
public class UserController {
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id) {
if (id.equals("0")) {
throw new UserNotFoundException("사용자를 찾을 수 없습니다.");
}
return "User Found";
}
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}
}
➡ UserNotFoundException
이 발생하면 HTTP 404와 함께 "사용자를 찾을 수 없습니다."
응답 반환.
📌 전역(Global) 예외 처리 (ControllerAdvice 사용)
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAllExceptions(Exception ex) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("서버 내부 오류 발생");
}
}
➡ 모든 컨트롤러에서 발생하는 예외를 한 곳에서 처리 가능.
4. 예외 처리 체인(Chain of Resolvers)
Spring MVC에서는 여러 개의 HandlerExceptionResolver를 체인(chain)으로 연결하여 순차적으로 실행할 수 있습니다.
📌 예외 처리 순서
- ExceptionHandlerExceptionResolver →
@ExceptionHandler
확인 - ResponseStatusExceptionResolver →
@ResponseStatus
확인 - DefaultHandlerExceptionResolver → Spring MVC 디폴트 예외 처리
- SimpleMappingExceptionResolver → 특정 예외와 뷰(View) 매핑
📌 처리 방식
ModelAndView
를 반환하면 에러 페이지를 렌더링- 텅빈
ModelAndView
를 반환하면 예외가 해결된 것으로 간주됨 null
을 반환하면 다음 Resolver가 실행됨- 모든 Resolver에서 처리되지 않으면 예외가 서블릿 컨테이너까지 전파됨
5. 서블릿 컨테이너의 디폴트 에러 페이지 처리
Spring MVC의 HandlerExceptionResolver
가 예외를 해결하지 못하면 서블릿 컨테이너가 디폴트 에러 페이지를 보여줄 수 있음.
이 디폴트 에러 페이지를 커스텀할 수도 있습니다.
📌 예제: web.xml에서 에러 페이지 설정
<error-page>
<location>/error</location>
</error-page>
➡ 모든 예외 발생 시 /error
페이지로 이동
📌 예제: /error
요청을 처리하는 컨트롤러
@RestController
public class ErrorController {
@RequestMapping(path = "/error")
public Map<String, Object> handleError(HttpServletRequest request) {
Map<String, Object> errorDetails = new HashMap<>();
errorDetails.put("status", request.getAttribute("jakarta.servlet.error.status_code"));
errorDetails.put("message", request.getAttribute("jakarta.servlet.error.message"));
return errorDetails;
}
}
➡ JSON 형식으로 에러 응답을 제공할 수도 있음.
🚀 Summary
1️⃣ Spring MVC는 예외 발생 시 HandlerExceptionResolver 체인을 실행하여 처리
2️⃣ 예외 처리기 종류
SimpleMappingExceptionResolver
: 예외 ↔ 뷰 매핑DefaultHandlerExceptionResolver
: Spring 디폴트 예외 처리ResponseStatusExceptionResolver
:@ResponseStatus
를 기반으로 예외 처리ExceptionHandlerExceptionResolver
:@ExceptionHandler
로 예외 처리
3️⃣ 서블릿 컨테이너의 디폴트 에러 페이지를 설정할 수도 있음
4️⃣ Spring Boot에서는/error
컨트롤러를 이용해 JSON 기반 에러 응답 제공 가능 🚀
출처 : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-servlet/exceptionhandlers.html
'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글
Multipart Resolver (0) | 2025.02.28 |
---|---|
View Resolution (0) | 2025.02.28 |
Interception (0) | 2025.02.28 |
Path Matching (0) | 2025.02.27 |
Processing (0) | 2025.02.27 |