[Spring] Spring MVC 예외 처리 - @ExceptionHandler, @ControllerAdvice, <error-page> 등
by 우와한개발자
[ Spring 예외처리 ]
| 방식 | 처리 레벨 | 적용 범위 | 주 사용 환경 |
| @ExceptionHandler | Spring | 해당 컨트롤러만 | 모든 환경 |
| XML ExceptionResolver | Spring | 전역 | Legacy / JSP |
| @ResponseStatus | Spring | 예외 클래스 단위 | 간단한 상태코드 |
| @ControllerAdvice | Spring | 전역 | REST API (현재 표준) |
| web.xml 에러페이지 | Tomcat | 전역 | Legacy / JSP |
- 컨트롤러 내부 @ExceptionHandler > @ControllerAdvice > XML ExceptionResolver > web.xml 에러페이지 순서로 우선 적용됨
- 어노테이션이 XML보다, XML이 Tomcat(web.xml)보다 우선 적용됨
1. @ExceptionHandler : 특정 컨트롤러 한정 예외처리
- 특정 컨트롤러 클래스 내부에서 발생하는 예외를 처리하는 방식
- 핸들러(컨트롤러) 메서드에 어노테이션을 선언
- 뷰 이름이나 ResponseEntity 반환 가능
- 다른 컨트롤러에 적용안됨
@Controller
public class MyController {
...
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleIllegal(IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
2. XML에 ExceptionResolver : 빈 설정하여 예외처리
- SimpleMappingExceptionResolver를 XML 빈으로 등록해 예외 클래스와 뷰(JSP) 이름을 매핑하는 방식
- exceptionMapping 변수의 의존성 설정으로 처리할 예외와 뷰를 설정
- Spring Legacy / JSP 기반 프로젝트에서 주로 사용
<!-- servlet-context.xml -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">error/error</prop>
<prop key="com.example.NotFoundException">error/notfound</prop>
</props>
</property>
<property name="defaultErrorView" value="error/default"/>
</bean>
3. @ResponseStatus : HTTP 상태코드로 예외처리
- 커스텀 예외 클래스에 @ResponseStatus를 붙여 해당 예외가 발생하면 자동으로 지정한 HTTP 상태코드를 응답하게 하는 방식
- 응답 body 커스터마이징이 어려움, reason이 응답 메시지에 그대로 노출됨
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Resource not found")
public class NotFoundException extends RuntimeException {
public NotFoundException(String message) {
super(message);
}
}
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
}
4. @ControllerAdvice : 글로벌 예외처리
- @ControllerAdvice 클래스를 별도로 만들어 애플리케이션 전역에서 발생하는 예외를 한 곳에서 통합 처리하는 방식
- @ExceptionHandler와 항상 같이 사용
- REST API에서는 @RestControllerAdvice를 주로 사용
- @ControllerAdvice 내부의 @ExceptionHandler 보다 컨트롤러 내부의 @ExceptionHandler가 우선순위가 더 높음
- 예외 처리 로직을 한 곳에 모아 관리하고 전역 적용하며 응답 body 자유롭게 커스터마이징 가능
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(NotFoundException e) {
ErrorResponse body = new ErrorResponse(404, e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(body);
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleBadRequest(IllegalArgumentException e) {
ErrorResponse body = new ErrorResponse(400, e.getMessage());
return ResponseEntity.badRequest().body(body);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAll(Exception e) {
ErrorResponse body = new ErrorResponse(500, "Internal Server Error");
return ResponseEntity.internalServerError().body(body);
}
}
5. web.xml : 에러페이지 설정으로 예외처리
- web.xml에서 HTTP 상태코드 또는 예외 클래스 기준으로 에러 발생 시 이동할 URL을 지정하는 방식
- Spring이 아닌 서블릿 컨테이너(Tomcat) 레벨에서 처리 → Spring이 잡지 못한 예외까지 처리 가능
- <mvc:view-controller>와 세트로 사용해 컨트롤러 없이 URL → 뷰 바로 매핑
<!-- web.xml -->
<error-page>
<error-code>404</error-code>
<location>/error/404</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error/error</location>
</error-page>
<!-- servlet-context.xml -->
<mvc:view-controller path="/error/404" view-name="error/404"/>
<mvc:view-controller path="/error/500" view-name="error/500"/>
<mvc:view-controller path="/error/error" view-name="error/error"/>
'프레임워크 > Spring' 카테고리의 다른 글
| [Spring] 파일 업로드 & 다운로드 - MultipartFile, ResponseEntity, HttpHeaders (0) | 2026.04.02 |
|---|---|
| [Spring] 인터셉터(Interceptor)란? - 동작 흐름과 설정 방법 및 주요 메서드 (0) | 2026.03.31 |
| [Spring] Spring MVC 응답 처리 - ModelAndView, ViewResolver, forward vs redirect (0) | 2026.03.31 |
| [Spring] Spring MVC Controller(핸들러) - 어노테이션과 파라미터 (0) | 2026.03.31 |
| [Spring] Spring MVC란? - DispatcherServlet과 전체 동작 흐름 (0) | 2026.03.30 |
블로그의 정보
우와한개발자 님의 블로그
우와한개발자