우와한 개발자

[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"/>

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기