이 글은 코드로 배우는 스프링 웹 프로젝트(남가람북스, 구멍가게 코딩단)을 읽고 공부한 내용을 바탕으로 정리한 글입니다.
스프링 MVC에서 Controller를 작성할 때 Exception을 처리하는 방식은 크게 두가지 방식으로 처리합니다.
@ExceptionHandler
와@ControllerAdvice
를 이용한 처리@ResponseEntity
를 이용하는 예외 메시지 구성
1. @ControllerAdvice
AOP(Aspect-Oriented-Programming) 방식을 이용하여 공통적인 예외사항에 대해서는 별도로 @ControllerAdvice를 이용해서 분리하는 방식입니다.
💡 AOP(Aspect-Oriented-Programming)이란?
'핵심적인 로직은 아니지만 프로그램에서 필요한 공통적인 관심사(cross-concern)은 분리하자'는 개념입니다.
예제를 위해서 exception 패키지를 생성하고, CommonExceptionAdvice
클래스를 생성하겠습니다. (CommonExceptionAdvice
클래스는 예외 처리 목적의 클래스로 별도의 로직을 처리하지 않습니다.)
import lombok.extern.log4j.Log4j;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@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";
}
}
@ControllerAdvice
: 해당 객체가 스프링의 컨트롤러에서 발생하는 예외를 처리하는 클래스라는 것을 알려줍니다.@ExceptionHandler
: 파라미터로 전달되는 예외타입을 처리한다는 것을 의미합니다. 위에서는@ExceptionHandler
의 파라미터로Exception.class
를 지정해줬으므로 모든 예외에 대한 처리가except()
메서드에서 처리됩니다. (특정한 타입의 예외를 다루고 싶다면Exception.class
대신에 처리하고 싶은 예외의 클래스를 지정해주면 됩니다!)
이때, @ControllerAdvice
등의 어노테이션을 스프링에 인식시켜줄려면 exception 패키지가 스캔될 수 있도록 dispatcher-servlet.xml
에서 <component-scan>
에 exception 패키지를 추가해주어야 합니다.
<context:component-scan base-package="com.hellomygreenworld.ex01.exception" />
except()
메서드의 리턴값이 "error_page
"라는 String
값이므로 views/error_page.jsp 파일을 작성해주겠습니다.
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page session="false" import="java.util.* "%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>error_page</title>
</head>
<body>
<h4><c:out value="${ exception.getMessage() }"></c:out></h4>
<ul>
<c:forEach items="${ exception.getStackTrace() }" var="stack">
<li><c:out value="${ stack }"></c:out></li>
</c:forEach>
</ul>
</body>
</html>
그리고 나서 sampleDto
의 age
값에 int
로 변환할 수 없는 값을 넣어 예외가 일어나게 하면 다음과 같이 작성한 error_page.jsp가 보여집니다.
2. 404 에러 페이지
지금까지는 Controller 처리에서 에러가 난 경우를 Exception 처리해주었고, 이번에는 잘못된 URL을 호출할 때 보이는 404 에러를 처리해보도록 하겠습니다. 스프링 MVC의 모든 요청은 DispatcherServlet
을 이용해서 처리되므로(https://eunbin00.tistory.com/128) 404 같이 처리될 수 있도록 web.xml
을 수정합니다.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config/dispatcher-servlet.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>
Controller에는 NoHandlerFoundException
를 처리하도록 어노테이션과 함께 메서드를 추가로 작성합니다.
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handle404(NoHandlerFoundException ex) {
return "custom404";
}
그리고 views/custom404.jsp 페이지도 작성해줍니다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>404_error</title>
</head>
<body>
<h4>해당 URL은 존재하지 않습니다.</h4>
</body>
</html>
그러면 아래와 같이 존재하지 않는 페이지를 요청했을 때, 예외처리가 되는 것을 확인할 수 있습니다!
'Java > Spring' 카테고리의 다른 글
[Spring MVC] Persistence Tier CRUD 구현 (0) | 2023.01.11 |
---|---|
[Spring boot] Maria DB 설정 (0) | 2023.01.06 |
[Spring MVC] 파일업로드 처리 (0) | 2023.01.03 |
[Spring MVC] Controller (0) | 2023.01.03 |
[Spring MVC] 기본 구조 (0) | 2023.01.02 |
댓글