1. 程式人生 > >Springmvc 異常處理的優先順序

Springmvc 異常處理的優先順序

1、springMVC提供的異常處理主要有兩種方式

一種是直接實現自己的HandlerExceptionResolver,當然這也包括使用Spring已經為我們提供好的SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,

另一種是使用註解的方式實現一個專門用於處理異常的Controller——ExceptionHandler。

2、springMVC本身已經對其有了自身的實現——DefaultHandlerExceptionResolverSimpleMappingExceptionResolver,這兩者都是繼承自抽象類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>