코딩 도구/백엔드 개발 (Backend Development)
[Spring] 예외 처리와 오류 페이지 정리
MKISOS
2025. 4. 14. 06:05
반응형
스프링 MVC 2 - 예외 처리와 오류 페이지 정리
이 글은 인프런 김영한님의 "스프링 MVC 2편 - 백엔드 웹 개발 활용 기술" 강의의 '예외 처리와 오류 페이지' 파트를 수강하고 정리한 내용입니다.
실무에서 예외와 오류는 언제나 발생할 수 있으며, 사용자에게는 의미 있는 오류 화면을 제공하고 개발자에게는 디버깅 정보를 제공해야 한다. 이번 강의에서는 서블릿의 예외 처리, 스프링 부트의 오류 페이지 처리, 필터와 인터셉터의 예외 흐름, 스프링 부트의 자동 오류 처리 메커니즘까지 폭넓게 다룬다.
정리 및 흐름 요약
- 서블릿 예외 처리 (Exception, sendError)
- 서블릿 오류 페이지 등록 (web.xml 방식, 스프링 부트 방식)
- 오류 페이지 컨트롤러 구현 및 오류 정보 활용
- DispatcherType 이해 및 필터/인터셉터 중복 호출 방지
- 스프링 부트의 기본 오류 처리 메커니즘
- BasicErrorController와 오류 뷰 우선순위
- 오류 정보 노출 여부 설정 방법
1. 서블릿 예외 처리 기본
두 가지 방식
- Exception: 예외가 WAS까지 전달됨 → 500 오류
- response.sendError(...): HTTP 상태 코드 기반 오류 처리
@GetMapping("/error-ex")
public void errorEx() {
throw new RuntimeException("예외 발생!");
}
@GetMapping("/error-404")
public void error404(HttpServletResponse response) throws IOException {
response.sendError(404, "404 오류!");
}
- WAS는 오류 코드나 예외 타입에 맞는 기본 오류 페이지를 출력
2. 오류 페이지 등록 (서블릿 방식)
WebServerCustomizer를 활용해 오류 페이지 등록
factory.addErrorPages(
new ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404"),
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error-page/500"),
new ErrorPage(RuntimeException.class, "/error-page/500")
);
- 500 에러: sendError(500), RuntimeException 예외 모두 대응
- 오류 페이지는 다시 WAS를 거쳐 컨트롤러로 요청됨
@RequestMapping("/error-page/404")
public String errorPage404(HttpServletRequest request) {
log.info("errorPage 404");
return "error-page/404";
}
오류 HTML 예시
<h2>404 오류 화면</h2>
<p>오류 화면 입니다.</p>
3. 오류 페이지 작동 원리와 흐름
예외 발생 흐름
1. WAS <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외 발생)
2. WAS 오류 페이지 찾음 → /error-page/500 요청 발생
3. 다시 필터/서블릿/인터셉터 → 오류 컨트롤러 → View 렌더링
오류 정보 확인
request.getAttribute("jakarta.servlet.error.status_code")
request.getAttribute("jakarta.servlet.error.exception")
- 오류 정보는 request attribute에 담겨서 전달됨
4. DispatcherType과 필터 동작
DispatcherType 종류
- REQUEST: 기본 클라이언트 요청
- ERROR: 오류 요청
- FORWARD, INCLUDE, ASYNC 등도 있음
오류 페이지에서 필터 중복 방지 설정
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
- 오류 페이지 전용 필터를 만들고 싶다면 DispatcherType.ERROR 사용
5. 인터셉터와 오류 중복 호출 방지
인터셉터는 DispatcherType을 직접 제어할 수 없기 때문에 excludePathPatterns를 활용해야 한다.
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/error", "/error-page/**");
6. 스프링 부트의 자동 오류 처리
기본 제공
- /error 경로로 오류 요청을 자동 처리
- BasicErrorController 자동 등록
- ErrorMvcAutoConfiguration에서 설정됨
뷰 템플릿 우선순위
- templates/error/500.html, templates/error/404.html
- templates/error/5xx.html, 4xx.html
- templates/error.html
- 템플릿이 없으면 정적 리소스(static) 폴더 사용
7. 오류 정보 노출 제어
application.properties 설정:
server.error.include-exception=true
server.error.include-message=on_param
server.error.include-stacktrace=on_param
server.error.include-binding-errors=on_param
- on_param: 요청 파라미터에 따라 노출됨 (?trace&message= 등)
- 운영 환경에서는 반드시 제거해야 함
마무리 정리
- 서블릿의 예외 처리: Exception, sendError() 두 가지 방식 제공
- 오류 페이지는 예외/상태코드에 따라 설정 가능하며, WAS가 내부 요청 수행
- DispatcherType을 통해 필터 중복 호출을 방지할 수 있음
- 스프링 부트는 오류 페이지를 자동 등록하고, 개발자는 뷰 템플릿만 정의하면 됨
- 오류 상세 정보는 개발 시 디버깅에 활용하고, 운영 환경에서는 반드시 숨겨야 한다
반응형