在Javaconfiguration的spring404错误redirect

如你所知,在XML中,configuration这个的方法是:

<error-page> <error-code>404</error-code> <location>/my-custom-page-not-found.html</location> </error-page> 

但是我还没有find在Javaconfiguration中做到这一点的方法。 我尝试的第一种方法是:

 @RequestMapping(value = "/**") public String Error(){ return "error"; } 

它似乎工作,但它有检索资源的冲突。

有没有办法做到这一点?

在Spring框架中,有很多处理exception的方法(尤其是404错误)。 这是一个文档链接 。

  • 首先,您仍然可以在web.xml中使用error-page标签,并自定义错误页面。 这是一个例子 。
  • 其次,你可以为所有的控制器使用一个@ExceptionHandler ,像这样:

     @ControllerAdvice public class ControllerAdvisor { @ExceptionHandler(NoHandlerFoundException.class) public String handle(Exception ex) { return "404";//this is view name } } 

    为此,请在web.xml中将DispatcherServlet throwExceptionIfNoHandlerFound属性设置为true:

     <init-param> <param-name>throwExceptionIfNoHandlerFound</param-name> <param-value>true</param-value> </init-param> 

    您也可以将一些对象传递给错误视图,请参阅javadoc 。

自从Spring 4.2 RC3以来,最干净的解决scheme是使用扩展AbstractDispatcherServletInitializer的类中的新的createDispatcherServlet钩子(或者通过扩展AbstractAnnotationConfigDispatcherServletInitializer间接地):

 public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return null; } /* ... */ @Override protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) { final DispatcherServlet dispatcherServlet = super.createDispatcherServlet(servletAppContext); dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); return dispatcherServlet; } } 

然后,您可以使用全局@ControllerAdvice (一个用@ControllerAdvice注释的类),如参考文档中所述 。 在这个build议中,你可以用NoHandlerFoundException来处理NoHandlerFoundException ,如下所述。

这可能看起来像这样:

 @ControllerAdvice public class NoHandlerFoundControllerAdvice { @ExceptionHandler(NoHandlerFoundException.class) public ResponseEntity<String> handleNoHandlerFoundException(NoHandlerFoundException ex) { // prepare responseEntity return responseEntity; } } 

使用doc中描述的基于代码的Servlet容器初始化,并覆盖registerDispatcherServlet方法将throwExceptionIfNoHandlerFound属性设置为true:

 public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { WebConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected void registerDispatcherServlet(ServletContext servletContext) { String servletName = getServletName(); Assert.hasLength(servletName, "getServletName() may not return empty or null"); WebApplicationContext servletAppContext = createServletApplicationContext(); Assert.notNull(servletAppContext, "createServletApplicationContext() did not return an application " + "context for servlet [" + servletName + "]"); DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext); // throw NoHandlerFoundException to Controller dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet); Assert.notNull(registration, "Failed to register servlet with name '" + servletName + "'." + "Check if there is another servlet registered under the same name."); registration.setLoadOnStartup(1); registration.addMapping(getServletMappings()); registration.setAsyncSupported(isAsyncSupported()); Filter[] filters = getServletFilters(); if (!ObjectUtils.isEmpty(filters)) { for (Filter filter : filters) { registerServletFilter(servletContext, filter); } } customizeRegistration(registration); } } 

然后创build一个exception处理器:

 @ControllerAdvice public class ExceptionHandlerController { @ExceptionHandler(Exception.class) public String handleException(Exception e) { return "404";// view name for 404 error } } 

不要忘记在你的Springconfiguration文件中使用@EnableWebMvc注解:

 @Configuration @EnableWebMvc @ComponentScan(basePackages= {"org.project.etc"}) public class WebConfig extends WebMvcConfigurerAdapter { ... } 

对于Javaconfiguration,在DispatcherServlet有一个方法setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound) 。 通过将它设置为true我猜你正在做同样的事情

 <init-param> <param-name>throwExceptionIfNoHandlerFound</param-name> <param-value>true</param-value> </init-param> 

那么你可以在控制器build议中的NoHandlerFoundException.class中按照上面的答案说明

这将是一些东西

 public class WebXml implements WebApplicationInitializer{ public void onStartup(ServletContext servletContext) throws ServletException { WebApplicationContext context = getContext(); servletContext.addListener(new ContextLoaderListener(context)); DispatcherServlet dp = new DispatcherServlet(context); dp.setThrowExceptionIfNoHandlerFound(true); ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dp); dispatcher.setLoadOnStartup(1); dispatcher.addMapping(MAPPING_URL); } } 

在你的网页configuration类中,

 @Configuration public class WebConfig extends WebMvcConfigurerAdapter 

声明一个bean如下,

 @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html"); ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"); ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html"); container.addErrorPages(error401Page,error404Page,error500Page); } }; } 

将上述html文件( 401.html .etc)添加到/src/main/resources/static/文件夹。

希望这可以帮助

上面评论中提出的解决scheme确实有效:

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

简单的答案100%免费的XML:

  1. 设置DispatcherServlet属性

     public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { RootConfig.class }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] {AppConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true if(!done) throw new RuntimeException(); } } 
  2. 创build@ControllerAdvice

     @ControllerAdvice public class AdviceController { @ExceptionHandler(NoHandlerFoundException.class) public String handle(Exception ex) { return "redirect:/404"; } @RequestMapping(value = {"/404"}, method = RequestMethod.GET) public String NotFoudPage() { return "404"; } }