[Spring] 404 Error Custom하기 (@ExceptionHandler사용, NoHandlerFoundException Throw 안될때)

GilLog·2021년 7월 21일
0

Spring

목록 보기
14/22

🙆‍♂️ import 🙇‍♂️

HOWTO handle 404 exceptions globally using Spring MVC configured using Java based Annotations

[java] 스프링 부트 REST 서비스 예외 처리[리뷰나라]


Spring에서 아래와 같이 ControllerAdvice@ExceptionHandler를 사용해 Error들을 Handling 할 수 있는데,
@RestControllerAdvice는 @ResponseBody가 붙은 @ControllerAdvice

@RestControllerAdvice
public class ExceptionController {
	@SuppressWarnings("unused")
	private static final Logger LOG = Logger.getLogger(ExceptionController.class);
	@Autowired
	private ExceptionService exceptionService;

	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	protected ResponseEntity<ErrorResponse> handleHttpRequestMethodNotSupportedException(
			HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
		exceptionService.errorLog(e, request);
		return new ResponseEntity<>(
				new ErrorResponse(HttpStatus.METHOD_NOT_ALLOWED.value(), "MethodNotSupported", e.getMessage()),
				HttpStatus.METHOD_NOT_ALLOWED);
	}

	@ExceptionHandler(NoHandlerFoundException.class)
	protected ResponseEntity<ErrorResponse> handleNoHandlerFoundException(NoHandlerFoundException e,
			HttpServletRequest request) {
		exceptionService.errorLog(e, request);
		return new ResponseEntity<>(new ErrorResponse(HttpStatus.NOT_FOUND.value(), "Not Found", e.getMessage()),
				HttpStatus.NOT_FOUND);
	}

	@ExceptionHandler(Exception.class)
	protected ResponseEntity<ErrorResponse> handleException(Exception e, HttpServletRequest request) {
		exceptionService.errorLog(e, request);
		return new ResponseEntity<>(new ErrorResponse(HttpStatus.BAD_REQUEST.value(), request.getSession().getId()),
				HttpStatus.BAD_REQUEST);
	}

	@ExceptionHandler(JwtException.class)
	protected ResponseEntity<ErrorResponse> handleJwtException(JwtException e, HttpServletRequest request) {
		exceptionService.errorLog(e, request);
		return new ResponseEntity<>(new ErrorResponse(HttpStatus.UNAUTHORIZED.value(), "JwtException", e.getMessage()),
				HttpStatus.UNAUTHORIZED);
	}

	@ExceptionHandler(AuthenticationException.class)
	protected ResponseEntity<ErrorResponse> handleAuthenticationException(AuthenticationException e,
			HttpServletRequest request) {
		exceptionService.errorLog(e, request);
		return new ResponseEntity<>(
				new ErrorResponse(HttpStatus.UNAUTHORIZED.value(), "AuthenticationException", e.getMessage()),
				HttpStatus.UNAUTHORIZED);
	}
}

404 Error을 Handling하기 위해 NoHandlerFoundException@ExceptionHandler로 Handling 해보려 했지만 적용되지 않았다.


이를 해결하기 위해DispatcherServletHandlerMapping에게 Request를 처리할 Handler를 찾도록 요청할 때,

Handler를 찾지 못할 경우 NoHandlerFoundException을 Throw 하게 해주어야 한다.


방법은 서버 환경에 따라 다른데, 자신의 서버 환경에 따라 아래 방법을 설정하자.

Spring

Spring - Tomcat web.xml

	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/config/servlet-context.xml</param-value>
		</init-param>
		<init-param>
			<param-name>throwExceptionIfNoHandlerFound</param-name>
			<param-value>true</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
		<async-supported>true</async-supported>
	</servlet>

Spring Boot

Spring Boot - extends SpringBootServletInitializer

@ComponentScan()
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
        DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    }
}

Spring Boot - application.properties

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

Spring Boot - *.yml

spring:
# error 404
mvc:
  throw-exception-if-no-handler-found: true
  dispatch-options-request: false

21-08-28 추가 위 방법 말고 아래 방법으로 성공했다는 의견 존재

spring:
web:
    resources:
        add-mappings: false 

위 설정 이후정상적으로 NoHandlerFoundException이 Throw되어,

@ExceptionHandler(NoHandlerFoundException.class)에서 Handling 할 수 있었다.

오늘도 해결 완료 :) 🙆‍♀️

profile
🚀 기록보단 길록을 20.10 ~ 22.02 ⭐ Move To : https://gil-log.github.io/

3개의 댓글

comment-user-thumbnail
2021년 8월 27일

Spring Boot - *.yml 적용시
dispatch-options-request: false 는 안써도 되고
spring:
web:
resources:
add-mappings: false
를 적용해야 했습니다.

2개의 답글