프로젝트[종료]

17. Spring Boot 오류 처리하기

알렉스 페레이라 2023. 6. 1. 19:39

웹개발을 하다보면 정말 많은수의 에러페이지와 마주한다.

 

현재 잘 운영중인 사이트도 억지로 파라미터를 변조하거나, PostMan따위로 허위값을 보내면 에러페이지를 확인할 수 있다.

 

아래 두가지 에러페이지를 비교해보자.

 

내 포탈의 에러페이지(부끄러움)

 

네이버의 에러페이지

 

엄청깔끔할것 같아서 네이버를 선택했는데 네이버도 그렇게 깔끔한 에러페이지는 아닌것같다.

 

네이버가 나은것같다.

 

여하튼, 위와같이 에러가 발생했을시, 사용자가 마주하는 에러페이지가 내 포탈과 같다면, 사용자의 신뢰도는 매우 떨어지게 될것이다. 

 

그렇다면 HTTP에러가 발생했을시에, 특정 화면을 렌더링함으로써 사용자에게 신뢰를 주는 에러페이지를 만들어보자.

 

1.WAS에서 설정하는법 - Tomcat에서, ~{CATALINA_HOME}/conf/web.xml에 아래와 같이 에러와, 해당 에러가 발생했을시 보낼 페이지를 mapping하고는 했다. 하지만 이제 xml파일에 설정하는것은 구식이다.

 

2.WEB에서 설정하는법 - Apache Web Server에서. ~{APACHE_HOME}/conf/http.conf에 아래와 같이 설정해 줄 수 있다.

#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 402 http://www.example.com/subscription_info.html

하지만 WEB에서 설정하는방법도 결국 WAS와 다를게 없고, 사실상 하드코딩이다.

 

3.Spring 활용(WebServerFactoryCustomizer)

Spring Boot가 제공하는 에러 페이지 Mapping방식을 사용한다. 특정에러가 발생하면, WAS단에서 특정 url을 호출한다.

ex) /error/404

package com.project.web.error;

import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
public class WebServerCustomizer implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
    @Override
    public void customize(ConfigurableWebServerFactory factory) {
        //404 에러일 때, 해당 request url을 mapping한다.
        ErrorPage error404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");

        //500 에러일 때, 해당 request url을 mapping한다.
        ErrorPage error500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");

        //그 외 에러일 때, 해당 request url을 mapping한다.
        ErrorPage errorEx = new ErrorPage(Exception.class, "/error/ex");
        
        factory.addErrorPages(error404, error500, errorEx);
    }
}

 

인터넷 서핑을 통해 404에러페이지 전용 HTML 템플릿을 다운받자.

귀엽다

 

ErrorController.java를 생성해 해당 에러요청에 대한 view를 mapping한다. 

package com.project.web.error;

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import java.io.IOException;

@Controller
public class ErrorTestController {
    @GetMapping("/error-404")
    public void error404(HttpServletResponse response) throws IOException {
        response.sendError(404, "404 error");
    }

    @GetMapping("/error-500")
    public void error500(HttpServletResponse response) throws IOException {
        response.sendError(500, "500 error");
    }

    @GetMapping("/error-ex")
    public void errorEx(HttpServletResponse response) throws Exception {
        throw new Exception("예외발생!");
    }
}

/error-404를 호출하면, response에서 404에러를 다시 호출한다. 그렇다면 WAS에서 이를 catch해서 /error/404를 그리는것.. 매우 복잡하다. 

 

 

또한 에러페이지는 인터셉터를 통과해야하기 때문에, WebConfig.java에 /error/** 파일들을 exclude한다.

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new SessionInterceptor())
                .order(0) //interceptor의 순서를 정한다.
                .addPathPatterns("/**") // [/**]는 전부 Interceptor의 범위에 있다는 뜻이다.
                .excludePathPatterns("/", "/sign/**", "/assets/**", "/images/**", "/error/**"); //다음과 같은 url은 interceptor에서 제외한다.
    }

 

점점 산으로 가는것 같지만.. 다 끝났다 서버를 재기동하고 http://localhost:9090/error-404를 호출해보자.

성공!

 

한 게시글로 끝내려고 했지만 너무 길어져서 2편까지 작성해야할것같다.