Springmvc 異常處理的優先順序
1、springMVC提供的異常處理主要有兩種方式,
①一種是直接實現自己的HandlerExceptionResolver,當然這也包括使用Spring已經為我們提供好的SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,
②另一種是使用註解的方式實現一個專門用於處理異常的Controller——ExceptionHandler。
2、springMVC本身已經對其有了自身的實現——DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver,這兩者都是繼承自抽象類AbstractHandlerExceptionResolver
而AbstractHandlerExceptionResolver是實現了HandlerExceptionResolver介面的唯一方法resolveException。並由此抽取出兩個抽象方法,一個是在進行異常處理之前執行的方法prepareResponse(exception, response),一個是進行異常解析的doResolveException(request, response, handler, exception)方法。
protected void prepareResponse(Exception ex, HttpServletResponse response) { if (this.preventResponseCaching) { preventCaching(response); } }
3、AbstractHandlerExceptionResolver 實現HandlerExceptionResolver介面的唯一方法resolveException ,在resolveException 呼叫了自己的抽象方法doResolveException,doResolveException方法留給了DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver實現
@Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (shouldApplyTo(request, handler)) { // Log exception at debug log level if (this.logger.isDebugEnabled()) { this.logger.debug("Resolving exception from handler [" + handler + "]: " + ex); } prepareResponse(ex, response); ModelAndView mav = doResolveException(request, response, handler, ex); if (mav != null) { // Log exception message at warn log level logException(ex, request); } return mav; } else { return null; } }
protected abstract ModelAndView doResolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex);
4、實現自己的HandlerExceptionResolver,
<span style="font-size:24px;">import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
public class TestException implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
ex.printStackTrace();
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
String name = handlerMethod.getBeanType().getPackage().getName();
// SystemUtils.println(TestException.class, null, name);
if (!name.contains("com.it.springmvc.controller")) {
return null;
}
}
return new ModelAndView("error/error").addObject("msg", "系統異常!請稍後重試");
}
}</span>
在spring-serlvet.xml配置檔案中新增
<!--異常處理 自己實現HandlerExceptionResolver類-->
<bean id="TestException" class="com.it.springmvc.exception.TestException"/>
5、同時在spring-serlvet.xml配置也可以新增一個SimpleMappingExceptionResolver bean,他與自己實現HandlerExceptionResolver bean, 誰在前,誰優先。
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- 表示當丟擲NumberFormatException的時候就返回名叫number的檢視 -->
<prop key="NumberFormatException">number</prop>
<prop key="NullPointerException">error/null</prop>
<!-- <prop key="RuntimeException">runtime</prop> -->
</props>
</property>
<!-- 表示當丟擲異常但沒有在exceptionMappings裡面找到對應的異常時 返回名叫defaultView的檢視-->
<property name="defaultErrorView" value="defaultView"/>
<!-- 定義在發生異常時檢視跟返回碼的對應關係 -->
<property name="statusCodes">
<props>
<!-- 表示在發生NumberFormatException時返回檢視number,然後這裡定義發生異常時檢視number對應的HttpServletResponse的返回碼是500 -->
<prop key="number">500</prop>
<prop key="null">503</prop>
<!-- <prop key="runtime">502</prop> -->
</props>
</property>
<!-- 表示在發生異常時預設的HttpServletResponse的返回碼是多少,預設是200 -->
<property name="defaultStatusCode" value="404"/>
</bean>