在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:
-
设置
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(); } }
-
创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"; } }
- 为什么要使用Spring的ApplicationContext层次结构?
- spring引导,logback和logging.config属性
- Spring MVC – 如何在Spring控制器中获取地图中的所有请求参数?
- 在应用程序启动时使用Spring MVC执行Java类
- Spring:以Map或Properties对象的forms访问所有Environment属性
- 有没有可能使空的RequestParam值使用defaultValue?
- Mockito,JUnit和Spring
- 什么时候在Spring中使用ModelAndView vs Model?
- 如何使用@PathVariable对Spring MVC控制器进行unit testing?