Spring Boot | 예외 처리 | Web API 액세스의 경우 json으로 반환하기


코드 작성

src/main/java/sample/springboot/web/HelloController.java

package sample.springboot.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

@Component
public class MyExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        if (isRestController(handler)) {
            return null;
        }

        ModelAndView mv = new ModelAndView();
        mv.setViewName("my-error");

        return mv;
    }

    private boolean isRestController(Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod)handler;

            return method.getMethod().getDeclaringClass().isAnnotationPresent(RestController.class);
        }

        return false;
    }
}

실행 결과

curl으로 테스트하기

$ curl http://localhost:8080/api
{"timestamp":1430490748092,"status":400,"error":"Bad Request","exception":"sample.springboot.web.MyException","message":"test exception","path":"/api"}

$ curl http://localhost:8080/api/null
{"timestamp":1430490749586,"status":500,"error":"Internal Server Error","exception":"java.lang.NullPointerException","message":"test exception","path":"/api/null"}

설명

  • 컨트롤러가 @RestController 어노테이션이 부여된 경우, resolveException()에서 null을 반환한다.
  • 그러면 응답이 기본 처리(handling) 방법으로 처리된다 (클라이언트가 curl 같은 브라우저 아니라면 json이 된다).
  • 브라우저에서 액세스하는 경우 기본 오류 페이지 (Whitelabel Error Page)가 표시된다.
  • 브라우저에서 화면 이동에 접근하려면 @Controller 어노테이션이 부여된 컨트롤러 클래스에 액세스하도록 하고 resolveException()에서 적절한 오류 페이지 날려 주도록한다.