Exception Handling in Spring MVC
NOTE: Revised April 2018 Spring MVC provides several complimentary approaches to exception handling but, when teaching Spring MVC, I often find that my students are confused or not comfortable with them. Today I'm going to show you the various options avai
spring.io
목표
Spring MVC는 예외처리를 위한 몇 가지 상호 보완적인 접근 방식을 제공한다.
목표는 가능한 한 컨트롤러 메서드에서 명시적으로 예외를 처리하지 않는 것이다. 예외는 별도의 전용 코드에서 처리하는 것이 더 나은 횡단 관심사이다.
- 컨트롤러 메서드 안에서 예외를 직접 처리하게 되면, 코드가 지저분해지고 유지보수가 어려워질 수 있다. 또한 모든 컨트롤러 메서드마다 예외 처리를 추가하면 코드의 중복이 발생하게 된다.
- 예외 처리는 컨트롤러 메서드와 분리하여, 별도의 전용 코드에서 처리하는 것이 더 효율적이다.
- 이를 통해 코드의 재사용성과 가독성을 높일 수 있다.
- @ExceptionHandler, @ControllerAdvice와 같은 어노테이션을 사용하여 예외 처리를 중앙화할 수 있다.
예외 처리를 위한 세 가지 옵션이 있다 : 예외별 처리, 컨트롤러별 처리, 전역적으로 처리
Spring Boot
Spring Boot는 스프링 프로젝트를 최소한의 설정으로 Spring 프로젝트를 설정할 수 있게 해준다.
Spring MVC는 기본적으로 에러 페이지를 제공하지 않는다. 기본 에러 페이지를 설정하는 가장 일반적인 방법은 SimpleMappingExceptionResolver을 사용하는 것이다.
그러나 Spring Boot는 기본적으로 에러 처리 페이지를 제공한다.
애플리케이션이 시작될 때, Spring Boot는 /error에 대한 매핑을 찾으려고 시도한다. 관례에 따라, /error로 끝나느 URL은 동일한 이름의 논리적인 뷰로 매핑된다.
- demo application에서 이 뷰는 error.html Thymeleaf 템플릿으로 매핑된다.
- JSP를 사용하는 경우, InternalResourceViewResolver 설정에 따라 error.jsp로 매핑된다.
- 실제 매핑은 설정한 ViewResolver에 따라 달라진다.
만약 /error에 대한 view-resolver mapping을 찾을 수 없다면 Spring Boot는 자체적으로 기본 에러 페이지를 정의한다.
- 이른바 Whitelabel Error Page : HTTP 상태 정보와 처리되지 않은 예외의 메시지와 같은 에러 세부 정보를 최소한으로 담고 있는 페이지
- 샘플 애플리케이션에서 error.html 템플릿 이름을 error2.html로 변경한 후 재시작하면 이 페이지가 사용된다.
RESTful 요청을 하는 경우(HTTP 요청이 HTML 이외의 응답 타입을 지정한 경우) Spring Bootsms "Whitelabel" 에러 페이지에 있는 동일한 에러 정보를 JSON 형식으로 반환한다.
$> curl -H "Accept: application/json" http://localhost:8080/no-such-page
{"timestamp":"2018-04-11T05:56:03.845+0000","status":404,"error":"Not Found","message":"No message available","path":"/no-such-page"}
Spring Boot는 또한 컨테이너에 대한 기본 오류 페이지를 설정한다. 이는 web.xml의 <error-page> 지시문과 동일하지만 매우 다르게 구현되었다. 스프링 MVC 프레임워크 외부에서 발생한 예외, 예를 들어 서블릿 필터에서 발생한 예외도 스프링 부트 기본 오류 페이지에 의해 보고된다.
web.xml 파일 내의 <error-page> 지시문
전통적인 Servlet 기반 웹 애플리케이션에서는 지시문을 사용하여 특정 HTTP 상태 코드나 예외에 대해 사용자 정의 에러 페이지를 설정할 수 있다.
<error-page>
<error-code>404</error-code>
<location>/error-404.html</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error-general.html</location>
</error-page>
- 404에러가 발생하면 'error-404.html'을, 모든 예외가 발생하면 'error-general.html'을 표시한다.
Spring Boot는 위와 같은 설정을 자동으로 처리한다.
- '/error' 경로에 기본적으로 매핑된 에러 핸들러를 재공한다. 이 에러 핸들러는 HTTP 상태 코드나 예외에 따라 적절한 에러 페이지를 반환한다.
- 기본적으로 제공되는 "Whitelabel Error Page"는 이 에러 핸들러가 반환하는 페이지 중 하나이다.
- 이 설정은 'web.xml' 파일을 사용하지 않고도 기본 에러 페이지를 처리할 수 있도록 해준다.
HTTP Status Code 사용
일반적으로 웹 요청을 처리하는 동안 처리되지 않은 예외가 발생하면 서버는 HTTP 500 response를 반환한다. 그러나 직접 작성된 예외는 @ResponseStatus로 주석을 달 수 있으며 이 annotation은 HTTP 사양에 정의된 모든 HTTP 상태 코드를 지원한다. 컨트롤러 메서드에서 annotation이 있는 예외가 발생하고 다른 곳에서 처리되지 않으면, 지정된 상태 코드와 함께 적절한 HTTP 응답이 자동으로 반환된다.
e.g) 주문이 누락된 경우의 예외
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No such Order") // 404
public class OrderNotFoundException extends RuntimeException {
// ...
}
예외를 사용하는 컨트롤러 메서드
@RequestMapping(value="/orders/{id}", method=GET)
public String showOrder(@PathVariable("id") long id, Model model) {
Order order = orderRepository.findOrderById(id);
if (order == null) throw new OrderNotFoundException(id);
model.addAttribute(order);
return "orderDetail";
}
이 메서드가 처리하는 URL에 포함된 주문 ID가 실제로 존재하지 않는 경우, HTTP 404 상태 코드와 함께 응답이 반환된다.
Controller Based Exception Handling
@ExceptionHandler 사용
컨트롤러에서 특정 예외를 처리하는 추가 메서드를 정의할 수 있다. 이러한 메서드는 동일한 컨트롤러의 요청 처리 메서드(@RequestMapping)에서 발생한 예외를 처리할 수 있다. 이러한 메서드는 다음과 같은 작업을 수행할 수 있다.
- @ResponseStatus이 없는 예외를 처리(일반적으로 직접 작성하지 않은 사전 정의된 예의)
- 라이브러리나 프레임워크에서 제공하는 사전 정의된 예외를 처리하는 것
- e.g) 데이터베이스와 관련된 예외, 파일 입출력 예외, 네트워크 예외 등
- 사용자를 전용 오류 뷰로 redirection
- 예외가 발생했을 때 사용자를 전용 에러 페이지로 안내한다.
- 완전히 사용자 정의된 오류 응답 생성
- 예외 처리에 대한 완전한 제어를 제공
- 예외 정보와 함께 사용자 정의 에러 페이지를 반환할 수 있다.
@Controller
public class ExceptionHandlingController {
// @RequestHandler methods
...
// Exception handling methods
// 1. 사전 정의된 예외를 HTTP 상태 코드로 변환
@ResponseStatus(value=HttpStatus.CONFLICT,
reason="Data integrity violation") // 409
@ExceptionHandler(DataIntegrityViolationException.class)
public void conflict() {
// 추가 작업 필요 없음
}
// 2. 에러를 표시할 특정 뷰 이름 지정
@ExceptionHandler({SQLException.class,DataAccessException.class})
public String databaseError() {
// 추가 작업 필요 없음, 논리적 뷰 이름을 반환하여 뷰 리졸버가 이를 처리함.
// 이 뷰에서는 예외에 접근할 수 없음(모델에 추가되지 않음)
return "databaseError";
}
// 3. 모델을 설정하고 직접 뷰 이름을 반환하는 완전한 제어
@ExceptionHandler(Exception.class)
public ModelAndView handleError(HttpServletRequest req, Exception ex) {
logger.error("Request: " + req.getRequestURL() + " raised " + ex);
ModelAndView mav = new ModelAndView();
mav.addObject("exception", ex);
mav.addObject("url", req.getRequestURL());
mav.setViewName("error");
return mav;
}
}
1. DataIntegrityViolationException이 발생했을 때 HTTP 상태코드 409(CONFLICT)와 함께 "Data integrity violation" 메시지를 반환, 이 예외는 데이터베이스 제약 조건을 위반했을 때 주로 발생한다.
2. SQLException이나 DataAccessException이 발생했을 때 databaseError라는 논리적 뷰 이름을 반환, Spring의 뷰 리졸버는 이 이름을 사용하여 실제 뷰 파일(e.g databaseError.html 또는 databaseError.jsp)을 찾아서 사용자에게 표시한다.
3. 모든 예외를 처리한다. 예외가 발생하면 로그에 예외 정보를 기록하고 'ModelAndView' 객체를 생성하여 예외 객체와 요청 URL을 모델에 추가한다. 그런 다음 'error'라는 뷰 이름을 설정하여 반환한다.
핸들러 메서드는 유연한 시그니처를 가지므로 HttpServletRequest, HttpServletResponse, HttpSession, 또는 Principle과 같은 서블릿 관련 객체를 매개변수로 받을 수 있다.
중요 사항
@ExceptionHandler 메서드의 매개변수로 Model을 사용할 수 없다. 대신, 위의 handleError() 예제와 같이 ModelAndView를 사용하여 메서드 내부에서 모델을 설정해야한다.
- resolveException 메서드의 시그니처에는 Model이 포함되어 있지 않기 때문이다.
Exceptions and Views
사용자에게 Java 예외 세부 정보와 stack-traces를 포함한 웹 페이지를 보여주고 싶지 않을 뿐만 아니라 보안 정책에 따라 예외 정보를 에러 페이지에 표시하지 말아야 할 수도 있다. 이는 Spring Boot의 Whitelave 에러 페이지를 반드시 재정의해야 하는 또 다른 이유ㅣㅇ다.
예외는 지원 및 개발 팀이 나중에 분석할 수 있도록 로그에 기록되어야 한다.
다음 방법이 편리할 수 있지만, 실제 운영 환경에서 최선의 방법은 아니다.
테스트를 돕기 위해 페이지 소스에 주석으로 예외 세부 정보를 숨기는 것이 유용할 수 있다. JSP를 사용하는 경우, 예외와 해당 스택 트레이스를 출력하기 위해 다음과 같은 방법을 사용할 수 있다.(숨겨진 <div>를 사용하는 것도 또 다른 옵션이다.)
<h1>Error Page</h1>
<p>Application has encountered an error. Please contact support on ...</p>
<!--
Failed URL: ${url}
Exception: ${exception.message}
<c:forEach items="${exception.stackTrace}" var="ste"> ${ste}
</c:forEach>
-->
Global Exception Handling
@ControllerAdvice 클래스 사용
controller advice는 동일한 예외 처리 기술을 개별 컨트롤러가 아닌 전체 애플리케이션에 적용할 수 있다. 이를 사용하여 annotation 기반 인터셉터를 만들 수 있다.
@ControllerAdvice로 annotation이 된 클래스는 controller-advice가 되며, 다음 세 가지 유형의 메서드를 지원한다.
- 예외 처리 메서드 : @ExceptionHandler로 애너테이션된 메서드
- 모델 향상 메서드 : 모델에 데이터를 추가하는 @ModelAttribute로 애너테이션된 메서드. 이 속성들은 예외 처리 뷰에는 사용할 수 없다.
- 바인더 초기화 메서드 : 폼 처리를 구성하는 @InitBinder로 애너테이션된 메서드
여기서는 예외 처리만 다룬다.
앞에서 본 ExceptionHandler를 controller-advice 클래스에 정의할 수 있으며, 이제 이러한 ExceptionHandler는 모든 컨트롤러에서 발생한 예외에 적용된다.
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ResponseStatus(HttpStatus.CONFLICT) // 409
@ExceptionHandler(DataIntegrityViolationException.class)
public void handleConflict() {
// 아무것도 할 필요 없음
}
}
모든 예외에 대해 기본 핸들러를 정의하려면 약간의 주의가 필요하다. annotation된 예외가 프레임워크에 의해 처리되도록 해야 한다.
- 먼저, 모든 예외를 처리하는 기본 핸들러를 정의해야 한다.(@ControllerAdvice, @ExceptionHandler 사용)
- 특정 예외에 대해 프레임워크가 처리하도록 하려면, 해당 예외에 대한 별도의 핸들러를 정의해야 한다. (e.g 사용자 정의 예외를 처리하는 핸들러를 추가할 수 있다.)
@ControllerAdvice
class GlobalDefaultExceptionHandler {
public static final String DEFAULT_ERROR_VIEW = "error";
@ExceptionHandler(value = Exception.class)
public ModelAndView
defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
// 예외가 @ResponseStatus로 주석이 달려있으면 이를 재발생시켜 프레임워크가 처리하도록 한다.
// AnnotationUtils는 스프링 프레임워크 유틸리티 클래스이다.
if (AnnotationUtils.findAnnotation
(e.getClass(), ResponseStatus.class) != null)
throw e;
// 그렇지 않으면 기본 오류 뷰를 설정하고 사용자에게 보낸다.
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
}
이렇게 하면 애플리케이션 전체에서 발생하는 예외를 중앙에서 관리하고 처리할 수 있다.
Going Deeper
HandlerExceptionResolver
Spring MVC 시스템에서 발생한 예외를 가로채고 처리하기 위해 HandlerExceptionResolver 인터페이스를 구현한 모든 Spring bean은 DispatcherServlet의 애플리케이션 컨텍스트에 선언될 수 있다. 이 인터페이스는 다음과 같은 형태이다.
public interface HandlerExceptionResolver {
ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex);
}
여기서 handler는 예외를 발생시킨 컨트롤러를 가리킨다. (Spring MVC에서 지원하는 핸들러는 @Controller 인스턴스만 있는 것이 아니라 HttpInvokerExporter나 WebFlow Executor와 같은 핸들러도 포함된다.)
MVC의 기본 Exception Handler
- MVC는 기본적으로 세 가지 exception handler를 생성한다.
- ExceptionHandlerExceptionResolver: 처리되지 않은 예외를 handler(controller)와 모든 controller advice의 @ExceptionHandler 메서드와 매칭시킨다.
- ResponseStatusExceptionResolver : @ResponseStatus로 애노테이션된 처리되지 않은 예외를 찾아서 처리한다/
- DefaultHandlerExceptionResolver : 표준 Spring 예외를 HTTP 상태 코드로 변환한다.(Spring MVC 내부적으로 사용된다.)
이 exception handler는 순서대로 연결되고 처리된다. 내부적으로 Spring은 이 작업을 수행하기 위해 HandlerExceptionResolverComposite라는 전용 bean을 생성한다.
원하는 경우, 자신의 custom exception handling system을 설정하기 위해 HandlerExceptionResolver을 구현할 수 있다. handler는 일반적으로 Spring의 Ordered 인터페이스를 구현하므로 handler가 실행되는 순서를 정의할 수 있다.
SimpleMappingExceptionResolver
Spring 프레임워크는 오랫동안 간단하지만 편리한 HandlerExceptionResolver 구현체인 SimpleMappingExceptionResolver를 제공해왔다. 이 구현체는 다음과 같은 기능을 제공한다.
- 예외 클래스 이름을 뷰 이름에 매핑 - 클래스 이름을 지정하기만 하면 된다. 패키지명은 필요하지 않는다.
- 기본 에러 페이지 지정 : 다른 곳에서 처리되지 않은 예외에 대해 기본적으로 사용할 에러 페이지를 지정할 수 있다.
- 로그 메시지 기록 : 기본적으로 비활성화되어 있지만 활성화할 수 있다.
- 예외 속성의 이름 설정
- 예외를 모델에 추가하여 뷰 내에서 사용할 수 있도록 예외 속성의 이름을 설정할 수 있다. 기본 속성 이름은 'exception'이며, 'null'로 설정하면 비활성화된다. @ExceptionHandler 메서드에서 반환된 뷰는 예외에 접근할 수 없지만, SimpleMappingExceptionResolver에 정의된 뷰는 예외에 접근할 수 있다.
Java 설정을 사용한 SimpleMappingExceptionResolver의 일반적인 설정 예제
@Configuration
@EnableWebMvc // Spring MVC 기본 설정을 선택적으로 설정
// (Spring Boot를 사용하지 않거나 @EnableWebMvc를 다른 곳에 지정하지 않은 경우)
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Bean(name="simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver
createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r =
new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");
mappings.setProperty("InvalidCreditCardException", "creditCardError");
r.setExceptionMappings(mappings); // 기본 매핑은 없음
r.setDefaultErrorView("error"); // 기본 에러 뷰는 없음
r.setExceptionAttribute("ex"); // 기본 속성 이름은 "exception"
r.setWarnLogCategory("example.MvcLogger"); // 기본 로그 카테고리는 없음
return r;
}
...
}
XML 설정을 사용한 예제
<bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<map>
<entry key="DatabaseException" value="databaseError"/>
<entry key="InvalidCreditCardException" value="creditCardError"/>
</map>
</property>
<!-- Spring Boot와의 상호 작용에 대한 참고 사항은 아래에 있다 -->
<property name="defaultErrorView" value="error"/>
<property name="exceptionAttribute" value="ex"/>
<!-- 예외를 로그로 기록할 때 사용할 로거의 이름을 설정한다. 기본적으로 설정되어 있지 않으므로 값을 설정하지 않으면 로그가 기록되지 않는다. -->
<property name="warnLogCategory" value="example.MvcLogger"/>
</bean>
- exceptionMappings
- 예외 클래스 이름을 뷰 이름에 매핑한다.
- e.g) DatabaseException 예외가 발생하면 databaseError 뷰를 보여준다.
- defaultErrorView
- 다른 곳에서 처리되지 않은 예외에 대해 기본적으로 사용할 에러 페이지를 지정한다. 이는 대부분의 애플리케이션 서버에서 Java 스택 트레이스를 표시하는 대신 적절한 에러 페이지를 보여줄 수 있도록 한다.
- exceptionAttribute
- 예외를 모델에 추가할 때 사용할 속성 이름을 설정한다. 기본 이름은 'exception'이며, 이 속성을 설정하여 뷰에서 예외 정보를 사용할 수 있다.
defaultErrorView 속성은 특히 유용하다. 이는 처리되지 않은 모든 예외가 적절한 애플리케이션 정의 오류 페이지를 생성하도록 보장한다. (대부분의 애플리케이션 서버의 기본값은 Java 스택 트레이스를 표시하는 것이다. 이는 사용자에게 절대 보여져서는 안 된다). Spring Boot는 "화이트 라벨" 오류 페이지를 통해 동일한 작업을 수행하는 또 다른 방법을 제공한다.
SimpleMappingExceptionResolver 확장
SimpleMappingExceptionResolver을 확장하는 것은 여러 가지 이유로 매우 일반적이다.
- 생성자를 사용하여 속성을 직접 설정 : 예외 로깅을 활성화하고 사용할 로거를 설정할 수 있다.
- buildLogMessage를 재정의하여 기본 로그 메시지를 재정의할 수 있다. 기본 구현은 항상 다음 고정 텍스트를 반환한다. :"Handler execution resulted in exception"
- doResolveException을 재정의하여 추가 정보를 오류 뷰에 제공할 수 있다.
public class MyMappingExceptionResolver extends SimpleMappingExceptionResolver {
public MyMappingExceptionResolver() {
// 로거 이름을 제공하여 로깅을 활성화
setWarnLogCategory(MyMappingExceptionResolver.class.getName());
}
@Override
public String buildLogMessage(Exception e, HttpServletRequest req) {
return "MVC exception: " + e.getLocalizedMessage();
}
@Override
protected ModelAndView doResolveException(HttpServletRequest req,
HttpServletResponse resp, Object handler, Exception ex) {
// super 메서드를 호출하여 ModelAndView를 가져옴
ModelAndView mav = super.doResolveException(req, resp, handler, ex);
// 전체 URL을 뷰에 제공 - ModelAndView는 addObject()를 사용하지만, Model은 addAttribute()를 사용합니다.
// 두 메서드는 동일하게 작동합니다.
mav.addObject("url", req.getRequestURL());
return mav;
}
}
ExceptionHandlerExceptionResolver 확장
ExceptionHandlerExceptionResolver를 확장하여 예외 처리를 커스터마이징할 수도 있다. doResolveHandlerMethodException 메서드를 재정의하면 된다. 이 메서드는 거의 동일한 시그니처를 가지지만, Handler 대신 HandlerMethod를 매개변수로 받는다.
사용 설정
이 확장된 ExceptionHandlerExceptionResolver가 사용되도록 하려면, 상속된 order 속성을 설정해야한다. 새로운 클래스의 생성자에서 order 속성을 MAX_INT보다 작은 값으로 설정하여 기본 ExceptionHandlerExceptionResolver 인스턴스보다 먼저 실행되도록 한다. Spring이 생성한 기본 인스턴스를 수정하거나 교체하는 것보다 자체 핸들러 인스턴스를 만드는 것이 더 쉽다.
ExceptionHandlerExceptionResolver를 확장하는 예제 코드
import org.springframework.core.Ordered;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyExceptionHandlerExceptionResolver extends ExceptionHandlerExceptionResolver {
public MyExceptionHandlerExceptionResolver() {
setOrder(Ordered.HIGHEST_PRECEDENCE); // 우선 순위를 최우선으로 설정
}
@Override
protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod,
Exception exception) {
// 사용자 정의 예외 처리 로직 추가
ModelAndView mav = new ModelAndView("customError");
mav.addObject("exception", exception);
mav.addObject("url", request.getRequestURL());
return mav;
}
}
Errors and REST
RESTful GET 요청에서도 예외가 발생할 수 있으며, 표준 HTTP 오류 응답 코드를 반환하는 방법은 이미 보았다. 그러나 오류에 대한 정보를 반환하고 싶으면 어떻게 해야할까?
간단하다. 먼저 오류를 담을 클래스를 정의한다.
public class ErrorInfo {
public final String url;
public final String ex;
public ErrorInfo(String url, Exception ex) {
this.url = url;
this.ex = ex.getLocalizedMessage();
}
}
이제 핸들러에서 @ResponseBody를 사용하여 이 클래스의 인스턴스를 반환할 수 있다.
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MyBadDataException.class)
@ResponseBody
public ErrorInfo handleBadRequest(HttpServletRequest req, Exception ex) {
return new ErrorInfo(req.getRequestURL().toString(), ex);
}
이렇게 하면 MyBadDataException이 발생했을 때, 요청된 URL과 예외 메시지를 포함한 ErrorInfo 객체를 HTTP 응답 본문에 JSON 형식으로 반환하게 된다.
What to Use When?
Spring은 다양한 선택지를 제공하기 때문에 어떤 방법을 사용해야 할지 고민될 수도 있다. 다음은 몇 가지 권장 사항이다. 그러나 XML 설정이나 애너테이션 사용에 대한 선호가 있으면 그것을 따라도 괜찮다.
- 직접 작성한 예외
- 직접 작성한 예외 클래스에는 @ResponseStatus 애너테이션을 추가하는 것을 고려한다.
- 다른 모든 예외
- @ControllerAdvice 클래스에 @ExceptionHandler 메서드를 구현하거나 SimpleMappingExceptionResolver 인스턴스를 사용
- 애플리케이션에 이미 SimpleMappingExceptionResolver가 구성되어 있는 경우, 새로운 예외 클래스를 추가하는 것이 @ControllerAdvice를 구현하는 것보다 더 쉬울 수 있다.
- 특정 컨트롤러의 예외 처리
- 컨트롤러에 @ExceptionHandler 메서드를 추가하여 해당 컨트롤러에서 발생하는 예외를 처리
주의사항
동일한 애플리케이션에서 이러한 방법들을 혼합하여 사용하는 경우 주의가 필요하다. 동일한 예외가 여러 방법으로 처리될 수 있는 경우 원하는 동작이 이루어지지 않을 수 있다.
- 컨트롤러의 @ExceptionHandler 메서드는 항상 @ControllerAdvice 인스턴스의 메서드보다 우선 선택된다.
- @ControllerAdvice 인스턴스의 처리 순서는 정의되지 않았다.
잡담
하나하나는 이해가 되는데 전체적으로 생각할려니깐 좀 어렵다... 이번주 과제에 적용하고 그러다보면 좀 괜찮아지겠지...
'Spring' 카테고리의 다른 글
[Spring] Spring vs Spring Boot (0) | 2024.07.09 |
---|---|
[Spring] Maven과 Gradle (0) | 2024.07.08 |
Validation in Spring Boot (0) | 2024.07.02 |
Validating Form Input (0) | 2024.07.02 |
Serving Web Content with Spring MVC (0) | 2024.06.28 |