新答案(2016-04-20)
使用Spring Boot 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的默认配置来处理静态资源,则资源处理程序将处理请求(最后排序,并映射到/ **,这意味着它将拾取应用程序中其他任何处理程序未处理的任何请求),因此调度程序Servlet不会有机会引发异常。
新答案(2015-12-04)
使用Spring Boot 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通常提供的很多有用的自动配置。使用Spring Boot时请格外小心。
原始答案:
经过大量研究并跟踪了此处发布的解决方案(感谢帮助!),并在Spring代码中进行了大量的运行时跟踪,最终我找到了一个可处理所有异常(不是错误,但请继续阅读)的配置。包括404。
步骤1-告诉SpringBoot在“找不到处理程序”的情况下停止使用MVC。我们希望Spring抛出异常,而不是将返回到“ / error”的视图返回给客户端。为此,您需要在一个配置类中有一个条目:
// 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;
}
}
这样做的缺点是它将替换默认的调度程序servlet。对于我们来说,这还不是问题,没有副作用或执行问题。如果出于其他原因要对调度程序servlet进行其他操作,则可以在这里进行操作。
第2步-现在,如果没有找到处理程序,spring boot将引发异常,那么可以在统一的异常处理程序中与其他任何异常一起处理:
@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”注释在这里很重要。似乎没有它,所有这些都不起作用。就是这样-您的Spring Boot应用程序现在将在上述处理程序类中捕获所有异常,包括404,您可以根据需要使用它们。
最后一点-似乎没有一种方法来捕获引发的错误。我有一个古怪的想法,就是使用方面来捕获错误并将其转换为上述代码可以处理的异常,但是我还没有时间实际尝试实现这些错误。希望这对某人有帮助。
任何意见/更正/增强将不胜感激。