[Spring] Controller의 Exception처리

msriver·2020년 6월 29일
0

Spring

목록 보기
14/16

Exception 처리

Spring MVC의 컨트롤러에서 예외상황을 고려해 코드를 작성하게 되면 작업량이 매우 많아지고 중복적이 된다.

Spring에서 Exception을 처리하는 방식은 다음과 같다.

  • @ControllerAdvice, @ExceptionHandler
  • @ResponseEntity

@ControllerAdvice는 AOP를 이용하여 공통적인 예외사항에 대해서 별도로 분리하여 처리하는 방식이다.

package org.zerock.exception;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import lombok.extern.log4j.Log4j;

@ControllerAdvice
@Log4j
public class CommonExceptionAdvice {
	
	@ExceptionHandler(Exception.class)
	public String except(Exception ex, Model model) {
		log.error("Exception........" + ex.getMessage());
		model.addAttribute("exception", ex);
		log.error(model);
		return "error_page";
	}
}

위와 같이 클래스 선언할때 붙여주면 이 클래스는 Controller에서 발생한 예외를 처리하는 클래스가 된다.
내부에 선언된 메서드에는 @ExceptionHandler가 붙어있는데 속성값으로 예외타입을 지정하여 해당 예외가 발생했을 때 수행될 메서드가 된다.

예제에서는 Exception.class를 사용하였으므로 모든 예외상황을 except메서드가 처리할 것이다.

위 컨트롤러어드바이스 객체는 org.zerock.exception 패키지에 속하도록 생성하였는데 이를 servlet-context.xml에서 인식할 수 없으므로 component-scan태그를 이용해 등록한다.

<context:component-scan base-package="org.zerock.exception"></context:component-scan>

404에러 페이지

WAS를 구동하면서 가장 흔하게 마주치는 것은 404 에러와 500 에러일 것이다.
HTTP의 Status code에서 400번대는 클라이언트측의 잘못된 요청때문에 일어난다. (ex.없는 경로의 자원을 요청한다)
500번대는 서버내부의 에러

기존에 JSP/Servelt으로 이용한 개발에서는 별도의 에러페이지를 web.xml을 이용하여 지정할 수 있었다.

보통 에러메세지는 엔드유저들에게 불친절하고 불필요한 정보들이 많다. 그렇기에 사용자에게 너가 ~~~를 잘못했고 ~~~를 하지말고 ~~~해야해! 라고 알려주기 보단 그냥 여긴 안되용! 하고 간단히 알려주는 것이 좋을 것이다.

즉 에러페이지를 custom하여 보여줄 수 있음.

Spring MVC의 모든 요청은 DispatcherServlet을 이용하여 처리되므로 404 에러도 같이 처리하게 web.xml을 수정한다.

<!-- Processes application requests -->
<servlet>
	<servlet-name>appServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>

기존에 저렇게 되어있는 부분에 <init-param\> 태그를 추가한다.

<!-- Processes application requests -->
<servlet>
	<servlet-name>appServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
	</init-param>
  	<init-param>
		<param-name>throwExceptionIfNoHandlerFound</param-name>
		<param-value>true</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>

테스트)
위에 작성한 Advice클래스에 아래 메서드를 추가

@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handle404(NoHandlerFoundException ex) {
	return "custom404";
}

이후 주소창에 없는 URL을 호출해봄으로써 테스트( 미리 custom404.jsp는 만들어둬야합니다.)

profile
NOBODY

0개의 댓글