스프링 부트는 오류 페이지는 기본으로 제공한다.
- ErrorPage 를 자동으로 등록한다. 이때 /error 라는 경로로 기본 오류 페이지를 설정한다.
- new ErrorPage("/error") , 상태코드와 예외를 설정하지 않으면 기본 오류 페이지가 보여진다.
- 서블릿 밖으로 예외가 발생하거나, response.sendError(...) 가 호출되면 모든 오류는 /error 를 호출하게 된다.
- BasicErrorController 라는 스프링 컨트롤러를 자동으로 등록한다.
- ErrorPage 에서 등록한 /error 를 매핑해서 처리하는 컨트롤러다.
- 오류가 발생했을 때 오류 페이지로 /error 를 기본 요청한다. 스프링 부트가 자동 등록한 BasicErrorController 는 이 경로를 기본으로 받는다.
- BasicErrorController 는 기본적인 로직이 모두 개발되어 있기에 개발자는 오류 페이지 화면만 BasicErrorController 가 제공하는 룰과 우선순위에 따라서 등록하면 된다.
뷰 선택 우선순위 (BasicErrorController 의 처리 순서)
- 뷰 템플릿이 정적 리소스보다 우선순위가 높다.
- 적용 대상이 없을 때 뷰 이름(error) resources/templates/error.html
오류 페이지 등록
- 해당 오류 코드가 발생하면 보여지는 페이지
- 404, 500처럼 구체적인 것이 4xx처럼 덜 구체적인 것 보다 우선순위가 높다.
- 5xx, 4xx 라고 하면 500대, 400대 오류를 처리해준다.
- 4xx: 401,402,403,405, ...(404는 구체적으로 생성했으므로 제외)
resources/templates/error/4xx.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
</head>
<body>
<div class="container" style="max-width: 600px">
<div class="py-5 text-center">
<h2>4xx 오류 화면 스프링 부트 제공</h2>
</div>
<div>
<p>오류 화면 입니다.</p>
</div>
<hr class="my-4">
</div>
</body>
</html>
resources/templates/error/404.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
</head>
<body>
<div class="container" style="max-width: 600px">
<div class="py-5 text-center">
<h2>404 오류 화면 스프링 부트 제공</h2>
</div>
<div>
<p>오류 화면 입니다.</p>
</div>
<hr class="my-4">
</div>
</body>
</html>
resources/templates/error/500.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
</head>
<body>
<div class="container" style="max-width: 600px">
<div class="py-5 text-center">
<h2>500 오류 화면 스프링 부트 제공</h2>
</div>
<div>
<p>오류 화면 입니다.</p>
</div>
<hr class="my-4">
</div>
</body>
</html>
BasicErrorController가 제공하는 기본 정보들
BasicErrorController 컨트롤러는 아래 정보를 model에 담아서 뷰에 전달한다. 뷰 템플릿은 이 값을 활용해서 출력할 수 있다.
- timestamp: Fri Feb 05 00:00:00 KST 2021
- status: 400
- error: Bad Request
- exception: org.springframework.validation.BindException
- trace: 예외 trace
- message: Validation failed for object='data'. Error count: 1
- errors: Errors(BindingResult)
- path: 클라이언트 요청 경로 (`/hello`)
사용 예시
<ul>
<li>오류 정보</li>
<ul>
<li th:text="|timestamp: ${timestamp}|"></li>
<li th:text="|path: ${path}|"></li>
<li th:text="|status: ${status}|"></li>
<li th:text="|message: ${message}|"></li>
<li th:text="|error: ${error}|"></li>
<li th:text="|exception: ${exception}|"></li>
<li th:text="|errors: ${errors}|"></li>
<li th:text="|trace: ${trace}|"></li>
</ul>
</ul>
오류 관련 내부 정보들은 고객이 해당 정보를 읽어도 혼란만 야기시킬 수 있기에 고객에게 노출시키는 것은 좋지 않다. 또 보안상 문제가 될 수 있다. 그래서 BasicErrorController에서 이 정보들을 model에 포함할 지 여부를 선택할 수 있다. 아래 application.properties를 보자.
application.properties
- server.error.include-exception=false : exception 포함 여부( true , false )
- server.error.include-message=never : message 포함 여부
- server.error.include-stacktrace=never : trace 포함 여부
- server.error.include-binding-errors=never : errors 포함 여부
기본 값이 never 인 부분은 다음 3가지 옵션을 사용할 수 있다.
- never : 사용하지 않음
- always :항상 사용
- on_param : 파라미터가 있을 때 사용
- 개발 서버에서 사용할 수 있지만, 운영 서버에서는 권장하지 않는다.
- http://localhost:8080/error-ex?message=&errors=&trace=
- 이런 식으로 정보가 노출될 수 있다.
사용자에게는 이쁜 오류 화면과 고객이 이해할 수 있는 간단한 오류 메시지를 보여주고 오류는 서버에 로그로 남겨서 로그로 확인해야 한다.
스프링 부트 오류 관련 옵션
- server.error.whitelabel.enabled=true : 오류 처리 화면을 못 찾을 시, 스프링 whitelabel 오류 페이지 적용
- server.error.path=/error : 오류 페이지 경로, 스프링이 자동 등록하는 서블릿 글로벌 오류 페이지 경로와 BasicErrorController 오류 컨트롤러 경로에 함께 사용된다.
확장 포인트
에러 공통 처리 컨트롤러의 기능을 변경하고 싶으면 ErrorController 인터페이스를 상속 받아서 구현하거나 BasicErrorController 상속 받아서 기능을 추가하면 된다.
정리
스프링 부트가 기본으로 제공하는 오류 페이지를 활용하면 오류 페이지와 관련된 대부분의 문제는 손쉽게 해결할 수 있다.
'스프링' 카테고리의 다른 글
EntityNotFoundException: Unable to find com.aloharoombackend.model.HomeImage with id 1 (0) | 2023.02.28 |
---|---|
Spring Boot 파일 업로드 용량 제한 설정 (0) | 2023.02.23 |
[스프링 MVC 2편] 로그인 처리2 - 필터, 인터셉터 (1) | 2022.07.14 |
[스프링 MVC 2편] 로그인 처리1 - 쿠키, 세션 (2) (0) | 2022.07.14 |
[스프링 MVC 2편] 로그인 처리1 - 쿠키, 세션 (1) | 2022.07.09 |