본문 바로가기
Java, Spring

[Spring Boot] custom error page

by 혀나Lee 2018. 9. 27.

웹사이트를 운영하다보면 404, 500 등의 에러페이지를 서버에서 기본으로 제공해주는 화면이 아닌 각 사이트의 디자인에 맞춰 변경해야 한다.

Tomcat 같은 경우 아래의 페이지를 기본으로 제공해준다.

tomcat 404 error

나는 위 페이지를 변경하기위해 검색해보니 대부분 web.xml, pom.xml 등의 .xml 설정파일을 통해 셋팅하는 방식이 많았다.

하지만, 내 프로젝트의 개발환경이 .xml을 사용하지 않고 view 코드를 resource 하위 폴더가 아닌 spring.mvc.view.prefix 설정을 따르고 있었기때문에 정보찾기가 힘들었다. (공식 사이트도 이해하기가 힘들었다..)

기본적으로 Spring Boot는 xml 파일을 강요하지 않기 때문에 프로젝트를 생성시에 web.xml 파일이 자동 생성되지 않는다. 
web.xml 파일로 에러페이지를 설정하는 방식은 여러가지가 있으며 구글 검색으로 많이 찾을 수 있다.

application.yml

spring:
...
mvc:
view:
prefix:
/WEB-INF/
suffix: .jsp
...

@Configuration 사용

발생하는 에러코드(HttpStatus)에 나타낼 ErrorPage를 설정한다.

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

@Configuration
public class ErrorConfig {

@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error"));
return factory;
}
}

ErrorController 상속

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;

@Controller
public class CustomErrorController implements ErrorController {

private static final String PATH = "/error"; // configure 에서 Redirect 될 path

@RequestMapping(value = PATH)
public String error(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

if (String.valueOf(status).equalsIgnoreCase(HttpStatus.NOT_FOUND.toString())) {
return "errors/404"; // /WEB-INF/errors/404.jsp
}
return "error";
}

@Override
public String getErrorPath() {
return PATH;
}
}

/WEB-INF/errors/404.jsp

<!DOCTYPE html>
<html lang="en">
<head>
<title>NOT FOUND</title>
</head>
<body>
<div class="cover">
<h1>404 NOT-FOUND</h1>
</div>
</body>
</html>

주의할 점은 config에서 new ErrorPage 시에 적은 path와 ErrorController 에 적은 PATH 가 동일해야하며, ErrorController 에서 return 해주는 값이 jsp 폴더 경로와 일치해야 한다는 점이다.

jsp 에서 error 내용 보여주기

나는 500 에러인 경우에 jsp 페이지에서 에러 내용을 보여주고 싶었다.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<c:out value="${requestScope['javax.servlet.error.exception']}"/>
...

위에서 생성한 500.jsp 파일에 taglib 를 import 시켜준 후, c:out 을 이용하여 exception을 출력해줄 수 있다.

exception 외에도 status code 및 message 등 종류는 아래와 같다.

javax.servlet.error.status_code
- 에러 상태 코드 출력
javax.servlet.error.exception_type
- 예외처리 클래스 출력
javax.servlet.error.message
- 오류 메세지 출력
javax.servlet.error.request_uri
- 문제가 되는 request uri 정보를 출력
javax.servlet.error.exception
- 발생한 예외처리 내용 출력
javax.servlet.error.servlet_name
- 에러가 난 서블릿 명 출력

위 에러 정보를 이용하면 커스텀 에러페이지를 한 페이지로 구현할 수도 있을 것 같다.


참조
1. Spring Boot 에러페이지 설정 (http://mirotic91.tistory.com/5)
2. EmbeddedServletContainerCustomizer in spring boot 2.0 (https://stackoverflow.com/questions/49406779/embeddedservletcontainercustomizer-in-spring-boot-2-0)


댓글