Springmvc 异常处理的优先级

时间:2022-11-26 11:11:13

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>  

6、资料参考http://elim.iteye.com/blog/1188161