rest api 서버를 개발하던 도중 인증실패시, 서비스에서 에러가 났을때 등에 대한 에러는 error response로 응답을 만들어 리턴해주도록 개발했었다.
@RestControllerAdvice를 만들어서 모든 exception을 받아서 처리하도록 하였다.
근데 문제는 잘못된 url로 요청하였을때, 예를들면 abc/{id}로 요청해야하는데 id를 생략한것 같은 경우이다. 이 경우 일반적으로 404에러인 상황이다.
근데 이 에러는 컨트롤러를 타지 않는다.
그래서 RestControllerAdvice에 안걸린다고 생각했다.
이름 그대로 RestControllerAdvice는 컨트롤러에 대한 에러만 잡는다고 생각이 들었다.
그래서 열심히 인터넷 서칭을 해보니 가장 적절한 답변을 찾았다.
https://stackoverflow.com/questions/30917782/spring-boot-404-error-custom-error-response-rest
일단 해결법은
@Bean
DispatcherServlet dispatcherServlet () {
DispatcherServlet ds = new DispatcherServlet();
ds.setThrowExceptionIfNoHandlerFound(true);
return ds;
}
디스패처 서블릿에서 NoHandlerFound에러를 뱉도록 새로 정의해주었다.
두번째로 RestControllerAdvice에 @EnableWebMvc어노테이션을 추가해주었다.
이렇게 두가지를 해주니 기존에 만들어 놓았던 RestControllerAdvice에 에러가 들어왔다.
일단 난 디스패처 서블릿에 대해 자세히 몰랐다. 이넘이 누구인고 하니 적절한 서블릿을 찾아서 분배해주는 녀석이다.
즉 컨트롤러 앞단에서 무슨 컨트롤러를 호출할 지 결정해준다.
현재 상황은 이 디스패처 서블릿이 적절한 컨트롤러를 못찾아서 디스패처 서블릿에서 에러가 난 상황이다. 근데 기본적으로 NoHandlerFound에러는 익셉션으로 처리하는것이 아닌 에러페이지를 보여주는 형태로 처리하도록 되어 있나보다.
그래서 우리가 404에러 페이지를 보는것이겠지..
그럼 이걸 에러페이지가 아니라 익셉셕으로 내도록 설정을 바꿔주면 되겠다.
그게 저 빈등록 부분이다. 함수 이름만 봐도 뭘 바꿨는지 알것같다.
저렇게 빈을 등록해준 후에 다시 rest api를 호출해봤다.
안된다.
그래서 다시 해당 링크를 확인해보니 @EnableWebMvc이라는 어노테이션이 붙어있었다.
나도 똑같이 저 어노테이션을 RestControllerAdvice에 추가하였더니 드디어 내가 원하던데로 익셉션이 RestControllerAdvice으로 핸들링 되었다.
저 어노테이션이 무엇인지 찾아보았다.
https://pangtrue.tistory.com/84
여기에 설명이 있다.
근데 사실 무슨 말인지 잘 모르겠다. 인터넷 서핑을 좀 더 하면 알 수 있겠지만
현재 시간관계상 해결됫고, 로깅도 남겼으니 다음에 기회가 되면 더 자세히 찾아보자
추가 - 소스에서 빈으로 등록하는 대신 설정으로도 가능하다.
프로퍼티에 다음 라인을 추가시키면 된다.
spring.mvc.throw-exception-if-no-handler-found=true