728x90

이번에는 @ControllerAdvice입니다. 개인적으로 가장 효율적인 방법이라고 봅니다.


@ControllerAdvice

ControllerAdvice가 모든 컨트롤러에서 발생한 예외를 맡습니다.

예제

<web.xml>

	<servlet>
		<servlet-name>action</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

<dispatcher-servlet.xml>

<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>

<ControllerAdvice 클래스>

@ControllerAdvice
public class ExampleAdvice extends ResponseEntityExceptionHandler {
	/**
	 * 로그.
	 */
	private static final Log LOG = LogFactory.getLog(ExampleAdvice.class);

	@ExceptionHandler(Throwable.class)
	public String handleException(final Exception e, Model model) {
		LOG.error("Throwable 예외 기록.", e);
		model.addAttribute("msg", "오류 발생 시 메시지 추가 테스트입니다.");
		return "/cmmn/egovError";
	}

	@ExceptionHandler(ExampleForbiddenException.class)
	public String handleException(final ExampleForbiddenException e, Model model) {
		LOG.error("ExampleForbiddenException 예외 기록.", e);
		model.addAttribute("msg", "오류 발생 시 메시지 추가 테스트입니다.");
		return "/cmmn/egovError";
	}
}

장단점 설명

Controller에 Advice를 줄 용도로 만든 클래스에 [@ControllerAdvice]어노태이션을 붙인다. 클래스 내의 오류 처리 메서드에는 [@ExceptionHandler]어노태이션을 붙인다.

[@ExceptionHandler]어노태이션이 붙은 메서드가 동작하게 하려면 [ExceptionHandlerExceptionResolver]를 반드시 설정해야 한다.(Spring 3.1 이후에 DispatcherServlet에 기본으로 설정되어 있다고 하는데, 동작하지 않을 때는 명시적으로 설정하자.)

만약 특정 컨트롤러에서만 독자적인 오류 처리가 필요한 경우, 해당 컨트롤러 내에 예외 처리 메서드를 작성하고 [@ExceptionHandler]어노태이션을 붙이면 된다. ControllerAdvice의 [@ExceptionHandler]보다 컨트롤러 내의 [@ExceptionHandler]가 우선된다.

장점 : 전체 컨트롤러에서 발생하는 오류를 처리해주는 기능을 클래스 하나로 해결할 수 있다. 오류 로그를 남겨도 좋고, 다른 추가 처리를 해도 좋다. 특정 컨트롤러에서만 독자적인 오류 처리가 필요한 경우 분리시킬 수 있는 것도 장점.

단점 : 별달리 없다.

총평 : 가성비가 좋다. -_-)b

참고

반응형
728x90

이번에는 ExceptionResolver 관련 간단한 정리입니다. 미리 준비되어 있는 ExceptionResolver가 몇 종류 있는데, 개인적으로는 ExceptionHandlerExceptionResolver만 쓸 줄 알아도 충분하다고 봅니다.


ExceptionResolver

DispatcherServlet에 ExceptionResolver를 선언하여 에러 발생 시 해당 ExceptionResolver가 처리하게 하는 방식이다.

예제

<web.xml>

	<servlet>
		<servlet-name>action</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

<dispatcher-servlet.xml>

<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>

<Controller 클래스>

	@ExceptionHandler({ IllegalArgumentException.class, ExampleException.class })
	@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Some parameters are invalid")
	public void onBadRequestException(final RuntimeException exception) {
		LOG.error("!오류 핸들러가 실행!", exception);
	}

[ExceptionHandlerExceptionResolver]는 예외 발생 시 [@ExceptionHandler]어노태이션이 붙은 메서드가 처리하게 한다.

장단점 설명

ExceptionResolver 클래스는 추상클래스[AbstractHandlerExceptionResolver]를 상속받거나, 인터페이스[HandlerExceptionResolver]를 구현하여야 한다. 두 경우 모두 메서드[resolveException]가 구현되어야 한다.

메서드[resolveException]은 다음과 같은 특징이 있다.

  • 인자로 Exception을 받는다. 예외를 로그에 남기는 등의 처리가 가능하다.
  • 반환형이 ModelAndView다. 이를 통해 출력할 뷰를 제어할 수 있다.

장점 : 로그를 남기는 등 추가 처리가 가능하다.

단점 : 별달리 없다.

총평 : 미리 지원해주는 ExceptionResolver가 몇 종류 있어서, 알아보고 사용하면 된다. 없으면 직접 상속받거나 구현한 클래스를 사용하면 된다. 다만 개인적으로는 ExceptionHandlerExceptionResolver와 @ControllerAdvice 연계가 가장 가성비가 좋다고 생각한다. @ControllerAdvice에 대해서는 다음에 설명한다.

참고

반응형

+ Recent posts