SpringMVC 异常处理顺序问题

问题:

已经自定义了异常处理类(如:MyExceptionResolver),但是程序出错后没有进入自定义的异常处理,而是显示其他错误(如:http 400)。


原因:

默认情况下,Spring MVC会事前注入3个HandlerExceptionResolver如下:
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

这时会按顺序调用HandlerExceptionResolver处理能够处理的异常,如果没有处理就返回null,这时会继续调用下一个,如果其中一个返回了ModelAndView则后面的将不会再调用:
// Check registered HandlerExceptionResolvers...
ModelAndView exMv = null;
for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
  exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
  if (exMv != null) {
    break;
  }
}

解决方法:

调整HandlerExceptionResolver执行顺序,可以通过实现接口org.springframework.core.Ordered 来解决。

默认的三个Order为Integer.MAX_VALUE,所以我们只有比它小就可以了如Integer.MIN_VALUE。springMVC中有三种自定义处理异常方式,参见我的博客《springMVC三种异常处理方式》,下面针对三种情况分别给出方案。

     (1)SimpleMappingExceptionResolver方式
<bean
		class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<!-- 定义默认的异常处理页面,当该异常类型的注册时使用 -->
		<property name="defaultErrorView" value="error">
		</property>
		<property name="order" value="0" />
		<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
		<property name="exceptionAttribute" value="ex"></property>
		<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常也页名作为值 -->
		<property name="exceptionMappings">
			<props>
				<prop key="etc.exception.MyException">error-my</prop>
				<!-- 这里还可以继续扩展对不同异常类型的处理 -->
			</props>
		</property>
	</bean>
     
(2)@ExceptionHandler方式
//使用@ExceptionHandler进行处理有一个缺点就是进行异常处理的方法必须与出错的方法在同一个Controller里面
	@ExceptionHandler(Exception.class)
	@Order(value=1)
	public ModelAndView resolveException(Exception ex){
		Map<String,Exception> map = new HashMap<String,Exception>();
		map.put("ex", ex);
		
		//根据获取的Exception参数进行不同View的跳转
		if (ex instanceof MyException) {
			return new ModelAndView("error-my",map);
		}else{
			return new ModelAndView("error",map);
		}
	}
    
(3)HandlerExceptionResolver方式
public class MyExceptionHandler implements HandlerExceptionResolver,Ordered{

	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		Map<String,Exception> map = new HashMap<String,Exception>();
		map.put("ex", ex);
		
		//根据获取的Exception参数进行不同View的跳转
		if (ex instanceof MyException) {
			return new ModelAndView("error-my",map);
		}else{
			return new ModelAndView("error",map);
		}
	}

	@Override
	public int getOrder() {
		// TODO Auto-generated method stub
		return Ordered.HIGHEST_PRECEDENCE;
	}

}



  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值