如何使用java配置和没有Web.xml处理Spring MVC中的404页面未找到exception

我想在我的Spring MVC Web应用程序中处理404页面未找到exception,我正在使用SPRING 4.2.5.RELEASE ,我已经阅读了有关此主题的几个问题,但类似的问题是使用不同的spring java配置。

我有一个全局exception处理程序控制器类,它具有我的所有exception,这个类工作正常,但我无法处理404页面未找到exception。

这是我按照教程学习的方法

1)我创建了一个名为ResourceNotFoundException的类,它从RuntimeException扩展而来,我把这个注释放在了类定义@ResponseStatus(HttpStatus.NOT_FOUND)

像这样:

 @ResponseStatus(HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException { } 

2)我在exception的控制器类中创建了这个方法

 @ExceptionHandler(ResourceNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleResourceNotFoundException() { return "notFoundJSPPage"; } 

但是,当我放置一个不存在的URL时,我收到此错误“找不到带HTTP的HTTP请求的映射”

我读过的问题说我需要启用Dispatcher的true选项,但由于我的配置与其他问题不同,我没有Web.xml所以我无法应用。

这是我的Config.java

 @EnableWebMvc @Configuration @ComponentScan({"config", "controllers"}) public class ConfigMVC extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/"); } @Bean public UrlBasedViewResolver setupViewResolver() { UrlBasedViewResolver resolver = new UrlBasedViewResolver(); resolver.setPrefix("/WEB-INF/jsp/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; } } 

这是我的WebInitializer

 public class WebInicializar implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(ConfigMVC.class); ctx.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); } } 

这是我的全局exception处理程序控制器

 @ControllerAdvice public class GlobalExceptionHandlerController { @ExceptionHandler(value = NullPointerException.class) public String handleNullPointerException(Exception e) { System.out.println("A null pointer exception ocurred " + e); return "nullpointerExceptionPage"; } @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(value = Exception.class) public String handleAllException(Exception e) { System.out.println("A unknow Exception Ocurred: " + e); return "unknowExceptionPage"; } @ExceptionHandler(ResourceNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleResourceNotFoundException() { return "notFoundJSPPage"; } } 

我创建的类扩展了Runtime Exception

 @ResponseStatus(HttpStatus.NOT_FOUND) public class ResourceNotFoundException extends RuntimeException{ } 

我通过将此行放在WebApplicationInitializer.class onStartup方法中解决了这个问题

这是我添加servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true");

这就是我添加新行的完整方法

 @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(ConfigMVC.class); ctx.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true"); } 

然后我在GlobalExceptionHandlerController.class创建了这个控制器方法

 @ExceptionHandler(NoHandlerFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String handle(NoHandlerFoundException ex) { return "my404Page"; } 

这解决了我的问题我删除了我的GlobalExceptionHandlerController.classhandleResourceNotFoundException控制器方法,因为它没有必要,我也删除了我创建的exception类ResourceNotFoundException.class

您还可以扩展AbstractAnnotationConfigDispatcherServletInitializer并覆盖此方法:

 @Override protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) { final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext); dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); return dispatcherServlet; } 

或者这一个:

 @Override public void customizeRegistration(ServletRegistration.Dynamic registration) { registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); } 

最后在你的ControlerAdvice使用:

 @ExceptionHandler(NoHandlerFoundException.class) public String error404(Exception ex) { return new ModelAndView("404"); } 

我发现zygimantus的答案由于某种原因没有用,所以如果你也有同样的问题,那么不要声明一个“@ExceptionHandler”,而是将其中一个添加到“@Configuration”类中。 我把它放在我的WebMvcConfigurerAdapter中

 @Bean public HandlerExceptionResolver handlerExceptionResolver(){ HandlerExceptionResolver myResolver = new HandlerExceptionResolver(){ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { //return your 404 page ModelAndView mav = new ModelAndView("404page"); mav.addObject("error", exception); return mav; } }; return myResolver; } 

但请确保您也遵循其余的zygimantus即

 dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); 

在任何控制器中添加以下代码并创建404页面

 @GetMapping("/*") public String handle() { return "404"; }