들어가기 전에
하기 포스팅은 "스프링부트 시작하기(김인우 저)" 책을 공부하며 적은 포스팅입니다. 이번 포스팅에서는 예외처리에 대해 살펴보도록 하겠습니다.
예외처리
스프링의 예외처리 방식은 크게 3가지로 나눌 수 있습니다.
- try/catch를 이용한 예외처리
- 각각의 컨트롤러단에서 @ExceptionHandler를 이용한 예외처리
- @ControllerAdvice를 이용한 전역 예외처리
try/catch를 사용한 예외처리의 경우 스프링이 아닌 자바의 예외처리 방법이므로 여기서는 다루지 않습니다. 그리고 @ExceptionHandler 어노테이션을 이용한 예외처리의 경우 컨트롤러별로 동일 예외처리를 추가해야 해서 코드 중복이 많아져 이번 포스팅에서는 3번 @ControllerAdvice를 이용한 전역 예외처리에 대해 알아보겠습니다.
@ControllerAdvice 추가하기
@ControllerAdvice 어노테이션을 이용하면 추가 설정 없이 쉽게 예외처리를 할 수 있습니다.
- XML 기반에서 @ControllerAdvice를 설정하기 위해서는 스프링 프레임워크의 Root Application Context와 Servlet Context에 대한 지식이 필요했습니다. 또한, XML 설정도 필요해서 사용하기가 쉽지 않았습니다. 하지만, 스프링부트에서는 단순히 어노테이션만 추가하면 쉽게 사용이 가능합니다.
src/main/java/board 밑에 common 패키지를 생성하고 ExceptionHandler 클래스를 만들어 하기 내용을 적어줍니다.
package board.common;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
@Slf4j
public class ExceptionHandler {
@org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
public ModelAndView defaultExceptionHandler(HttpServletRequest request, Exception exception) {
ModelAndView mv = new ModelAndView("/error/error_default");
mv.addObject("exception", exception);
log.error("exception", exception);
return mv;
}
}
@ControllerAdvice
: @ControllerAdvice 어노테이션을 사용하여 해당 클래스가 예외처리 클래스임을 알립니다.@org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
: 해당 메소드에서 처리할 예외를 지정합니다. 여기서는 Exception.class로 설정하여 모든 예외를 처리했습니다.- 실제 프로젝트를 진행할 때에는 다양한 예외처리를 위해 각각의 예외처리가 필요합니다. 즉, NullPointerException, NumberFormatException 등 자바의 기본 예외 및 프로젝트에 필요한 커스텀 예외를 포함해 각각의 예외에 맞는 적절한 예외처리를 해야합니다.
- 절대로 실제 프로젝트에서는 Exception.class를 사용해 한번에 모든 예외 처리하지 않도록 합니다.
- 여러 예외처리 메소드를 추가할 때에는 자바의 모든 예외는 Exception 클래스를 상속받음을 생각해야 합니다. 따라서, 코드상에서 Exception.class를 처리하는 메소드보다 위쪽에 각 예외처리 메소드를 두어야 정상적으로 처리됩니다.
- 즉, Exception.class 처리하는 메소드는 가장 마지막에 있어야 함
ModelAndView mv = new ModelAndView("/error/eror_default")
: 예외 발생 시, 보여줄 화면을 지정합니다. 어플리케이션 실행 중 에러가 발생하면 해당 에러에 따라 적절한 예외처리 화면이 필요합니다.log.error("exception", exception)
: 에러 로그를 출력합니다.
예외처리 화면 추가하기
template 폴더 밑에 error 폴더를 생성하고 error_default.html
파일을 생성하여 에러 발생 시 사용자에게 보여줄 화면을 만들어보겠습니다.
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>공통 에러 페이지</title>
<link rel="stylesheet" th:href="@{/css/style.css}"/>
</head>
<body>
<p>공통 에러 페이지</p>
<p th:text="${exception}"></p>
<ul th:each="list : ${exception.getStackTrace()}" th:text="${list.toString()}"></ul>
</body>
</html>
${exception}
: 에러 종류를 출력합니다.${exception.getStackTrace()}
: 에러의 상세 내용을 출력합니다.
예외처리 확인하기
트랜잭션 포스팅에서 에러를 발생시킬 때 사용한 int i = 10 / 0;을 게시판 목록 조회(/board/openBoardList.do) 컨트롤러 메소드에 추가하고 스프링부트 어플리케이션을 시작합니다. 그 후, 게시판 목록 조회를 하면 하기와 같이 공통 에러 페이지가 나오는 것을 확인할 수 있습니다. 또한, 이클립스의 콘솔에서 해당 에러가 동일하게 출력됨을 확인할 수 있습니다.
여기서는 예외처리 방법에 대한 실습으로 사용자에게 에러 상세 내용을 표시하도록 했습니다. 하지만 실제 프로젝트에서는 이렇게 에러 로그를 화면에 직접 보여주면 안 됩니다. 이러한 로그를 통해 프로그램 취약점이 드러나 공격을 받을 수 있기 때문입니다. 따라서, 프로젝트 진행 시 예외별 예외 처리 메소드를 Exception.class 처리하는 메소드 위에 추가하여 각 예외별로 적절한 예외처리를 해야 합니다.
'FRAMEWORK > Spring' 카테고리의 다른 글
[SpringBoot] 게시판 구현하기 13 (파일 삭제하기) - 책 응용편 (0) | 2020.12.31 |
---|---|
[SpringBoot] 게시판 구현하기 12 (파일 업로드와 다운로드) (4) | 2020.12.27 |
[SpringBoot] 게시판 구현하기 10 (스프링의 다양한 기능 살펴보기 - 트랜잭션) (0) | 2020.12.26 |
[SpringBoot] 게시판 구현하기 9 (스프링의 다양한 기능 살펴보기 - AOP) (0) | 2020.12.26 |
[SpringBoot] 게시판 구현하기 8 (스프링의 다양한 기능 살펴보기 - 인터셉터) (0) | 2020.12.26 |