brunch

You can make anything
by writing

C.S.Lewis

by 이수홍 Jul 13. 2016

스프링 부트 예외 1

스프링 부트 예외의 기본

스프링 부트를 사용하다가 예외를 커스터마이징 하려고 할 때 기존 스프링을 사용하는 사람 조차 당황할 때가 있다.

기존 스프링 MVC에서 예외 처리랑 조금 다르기 때문이다.

물론 기본적으로 제공하고 있는 속성을 사용하면 어느 정도 쉽게 사용 가능하다.

예외 관련 설정하는 방법으로는 몇가지가 있는데 한번 살펴보자.


1. 환경변수로만 설정하는 방법

# application.yml
# 에러 페이지의 URI를 설정 ( 예외가 발생하면 지정된 URI로 이동한다. )
server.error.path: /error

# 예외가 발생했을 시에 예외 스택트 레이스를 볼 것인가?
# never: 보지 않는다.(기본값)
# always: 항상 본다.
# on_trace_param: URI에 파라메터로? trace=true를 전달 시에만 본다.
server.error.include-stacktrace: never

# 스프링 부트에서 기본적으로 제공하는 에러 페이지를 볼 것인가? ( 기본값은 본다. )
# 안 본다고(false) 설정하면 기본 서블릿 컨테이너 에러 화면을 보게 된다.
server.error.whitelabel.enabled: true

기본적인 옵션으로는 선택할 수 있는 것이 많이 있지 않다.

참고로 어떤 URI를 선택하더라도 기본적으로 org.springframework.boot.autoconfigure.web.BasicErrorController에서 예외가 처리된다.


2. ErrorAttributes 인터페이스를 구현하는 방법

org.springframework.boot.autoconfigure.web.DefaultErrorAttributes 클래스를 참고하여 커스터마이징 한다.

참고로 ErrorAttributes는 기본적으로 스프링 부트에서 에러 처리하는 BasicErrorController에서 사용하는 인터페이스로 보통 예외 정보를 관리하게 된다.

DefaultErrorAttributes는 스프링 부트에서 기본적으로 사용하는 클래스인데 HandlerExceptionResolver를 구현하여 예외를 가져오는 기능을 가진다.

기본적으로 스프링 빈 형태로 선언만 하면 기본값으로 선언된 빈이 교체된다. (@Conditional의 힘!)

// ErrorAttributes 확장하여 @Bean으로 선언해서 기존 DefaultErrorAttributes를 교체
@Bean
public DefaultErrorAttributes errorAttributes() {
    return new DefaultErrorAttributes() {
        @Override
        public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
            Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
            errorAttributes.put("custom_data",
                    requestAttributes.getAttribute("custom_data", RequestAttributes.SCOPE_REQUEST));
            return errorAttributes;
        }
}

3. ErrorController 인터페이스를 구현하는 방법

스프링 부트에서는 예외가 발생하면 먼저 ErrorController 인터페이스를 찾아서 getErrorPath() 메서드를 실행시켜서 예외를 처리할 URI를 얻는다. 기본으로 설정된 클래스는 org.springframework.boot.autoconfigure.web.BasicErrorController 이다. 내부에서는 getErrorPath()로 가져온 URI의 요청도 처리하는 역할도 가지고 있다.

커스터마이징시에는 해당 클래스를 참고해서 확장하면 된다.

2번에서 이야기한 ErrorAttributes와 마찬가지로 스프링 빈으로 선언만 하면 된다.

@Bean
public BasicErrorController errorController(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
    return new BasicErrorController(errorAttributes, serverProperties.getError()) {
        protected Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
            Map<String, Object> errorAttr = super.getErrorAttributes(request, includeStackTrace);
            // custom
            return errorAttr;
        }
    };
}

4. 기본 에러 화면만 바꾸는 방법

스프링 부트에서 기본적인 에러 화면은 알다시피 하얀색 화면이다.

커스터마이징 하는 방법은 간단하다.  
View 객체에서 error라는 이름 가진 빈을 선언하면 된다.

참고로 에러내용은 model 객체에서 "error"를 가져와서 확인하면 된다.

@Bean(name = "error")
public View customErrorView() {
    // 관련 View class를 구현
}

다음 브랜치에는 좀 더 내부로 들어가서 어떻게 구현되는지 한번 살펴보겠다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari