java config 解决 error-page 问题 (暴力方法)
最近在做毕业设计,使用的是java config方式配置spring mvc,问题是真的多。
废话不多讲,进入正题。
如何使用java config 配置 web.xml的error页,
百度了很多,stackoverflow也查了很多帖子,比较一致的回答都是配置HandlerException
先以用户自定义异常为例(404是重点,也是让我头疼了一晚上的地方)以下是代码:
/**
* 系统异常,异常id在ExceptionConstant中定义
*
* @param systemException 系统异常
* @return 根据异常id返回异常页面
*/
@ExceptionHandler({SystemException.class})
public String processException(SystemException systemException) {
return systemException.getExceptionStatus().getResponseView();
}
SystemException是我自定义的异常,responseView是对应异常id的视图名
这样,用户自定义的异常就能被catch住,并交给配置好的视图解析器处理。
下面说说404,根据官方给出的异常类,我们应该在HandlerException中,捕获NoHandlerFoundException
这样,找不到对应handler的url就会被以这个异常的形式抛出,然后被我们自定义的异常controller捕获并处理,
理所当然,代码应该是这样:
/**
* 找不到资源
*
* @return 返回404页面
*/
@ExceptionHandler(NoHandlerFoundException.class)
public String noHandlerFoundException() {
return "redirect:" + ERROR_404;
}
当我们理所应当的以为这样配置能够将找不到资源的404错误捕获时,突如其来的默认404错误页就给了我一巴掌,
不得不说,spring的坑真的是多(其实是我没学好(●'◡'●))
再查阅了stackoverflow之后,明白了,spring mvc默认的dispatcher是不允许404这样的错误以异常的形式穿透到controller里的,我蛮还要手动开启这个功能,我们需要在自定义的web初始器中,重写createDispatcherServlet方法,并在返回dispatcher前,将throwExceptionIfNoHandlerFound开启,代码如下:
@Override
protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
final DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
ok,一切就为,测试走起
啪唧,又是一巴掌
咱们的配置还是没有见效
首先,明确一点,咱们的大方向是没有错的,但是,细节方面欠缺一点
那么,咱们debug一下,看看spring内部到底是怎么工作的
废话不讲,直接上结论:
每个url被拦截器捕获之后,会对这个url进行handler的解析,当找不到handler的时候,再看能不能够抛出是这异常(throwExceptionIfNoHandlerFound==true?)
那么,请求不到的资源理应不会有handler啊,其实不然,在spring中默认注册了一个defaultServletHttpRequestHandler给我们用,也就是说,就算咱么配置一切正确,找不到的资源,还是会有handler,那么,我们要做的就是,屏蔽这个默认handler,让找不到资源的错误,以异常形式抛出,下面的代码就很暴力了,直接修改spring mvc中的getHandler方法,代码如下:
@Override
protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
final DispatcherServlet dispatcherServlet = new DispatcherServlet(){
@Override
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.getHandlerMappings() != null) {
for (HandlerMapping hm : this.getHandlerMappings()) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null&& !(handler.getHandler() instanceof DefaultServletHttpRequestHandler)) {
return handler;
}
}
}
return null;
}
{
setApplicationContext(servletAppContext);
}
};
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
测试走起,找不到资源的url成功得跳回了我们定义的错误页( •̀ ω •́ )y