새로운 답변 (2016-04-20)
스프링 부트 1.3.1.RELEASE 사용하기
새로운 1 단계 -application.properties에 다음 특성을 추가하는 것이 쉽고 방해가되지 않습니다.
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
기존 DispatcherServlet 인스턴스를 수정하는 것보다 훨씬 쉽습니다 (아래 참조)! -JO '
전체 RESTful 애플리케이션으로 작업하는 경우 정적 자원을 처리하기 위해 Spring Boot의 기본 구성을 사용하는 경우 자원 핸들러가 요청을 처리하기 때문에 정적 자원의 자동 맵핑을 사용하지 않는 것이 매우 중요합니다. ** 즉, 응용 프로그램의 다른 처리기가 처리하지 않은 요청을 선택하므로 디스패처 서블릿은 예외를 던질 기회가 없습니다.
새로운 답변 (2015-12-04)
스프링 부트 1.2.7.RELEASE 사용하기
새로운 1 단계 – "throExceptionIfNoHandlerFound"플래그를 설정하는 훨씬 덜 관입적인 방법을 찾았습니다. 아래의 DispatcherServlet 대체 코드 (1 단계)를 애플리케이션 초기화 클래스에서이 코드로 바꾸십시오.
@ComponentScan()
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {
private static Logger LOG = LoggerFactory.getLogger(MyApplication.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
이 경우 기존 DispatcherServlet에 플래그를 설정하여 Spring Boot 프레임 워크에 의한 자동 구성을 유지합니다.
@EnableWebMvc 주석은 Spring Boot에 치명적입니다. 예,이 주석은 아래 설명 된대로 모든 컨트롤러 예외를 포착 할 수있는 것과 같은 기능을 가능하게하지만 Spring Boot가 일반적으로 제공하는 유용한 자동 구성을 많이 제거합니다. 스프링 부트를 사용할 때는 매우주의해서 주석을 사용하십시오.
원래 답변 :
여기에 게시 된 솔루션에 대한 더 많은 연구와 후속 조치 (도움을 주셔서 감사합니다!)와 스프링 코드에 대한 소량의 런타임 추적이 없으면 결국 모든 예외 (오류가 아니라 읽기)를 처리하는 구성을 찾았습니다. 404 포함.
1 단계- "처리기를 찾을 수 없음"상황에서 MVC 사용을 중지하도록 SpringBoot에 지시하십시오. 우리는 클라이언트에게 뷰 리다이렉션을 "/ error"로 리턴하는 대신 Spring이 예외를 던지기를 원한다. 이렇게하려면 구성 클래스 중 하나에 항목이 있어야합니다.
// NEW CODE ABOVE REPLACES THIS! (2015-12-04)
@Configuration
public class MyAppConfig {
@Bean // Magic entry
public DispatcherServlet dispatcherServlet() {
DispatcherServlet ds = new DispatcherServlet();
ds.setThrowExceptionIfNoHandlerFound(true);
return ds;
}
}
이것의 단점은 기본 디스패처 서블릿을 대체한다는 것입니다. 부작용이나 실행 문제가 나타나지 않고 아직 문제가되지 않았습니다. 다른 이유로 디스패처 서블릿을 사용하여 다른 작업을 수행하려는 경우이 작업을 수행 할 수 있습니다.
2 단계- 이제 핸들러가 발견되지 않으면 스프링 부트에서 예외가 발생하므로 해당 예외는 통합 예외 핸들러에서 다른 예외와 함께 처리 될 수 있습니다.
@EnableWebMvc
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(Throwable.class)
@ResponseBody
ResponseEntity<Object> handleControllerException(HttpServletRequest req, Throwable ex) {
ErrorResponse errorResponse = new ErrorResponse(ex);
if(ex instanceof ServiceException) {
errorResponse.setDetails(((ServiceException)ex).getDetails());
}
if(ex instanceof ServiceHttpException) {
return new ResponseEntity<Object>(errorResponse,((ServiceHttpException)ex).getStatus());
} else {
return new ResponseEntity<Object>(errorResponse,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
Map<String,String> responseBody = new HashMap<>();
responseBody.put("path",request.getContextPath());
responseBody.put("message","The URL you have reached is not in service at this time (404).");
return new ResponseEntity<Object>(responseBody,HttpStatus.NOT_FOUND);
}
...
}
여기서는 "@EnableWebMvc"주석이 중요하다고 생각합니다. 이것 없이는 아무것도 작동하지 않는 것 같습니다. 이제 스프링 부트 앱이 위의 핸들러 클래스에서 404를 포함한 모든 예외를 포착하고 원하는대로 처리 할 수 있습니다.
마지막 요점-던진 오류를 잡을 수있는 방법이없는 것 같습니다. 나는 측면을 사용하여 오류를 잡아서 위의 코드가 처리 할 수있는 예외로 바꾸는 것에 대한 엉뚱한 아이디어를 가지고 있지만 실제로 구현하려고 시도 할 시간이 없었습니다. 이것이 누군가를 돕기를 바랍니다.
모든 의견 / 수정 / 향상을 부탁드립니다.