java深入 - Spring 异常处理HandlerExceptionResolver

Spring的异常统一处理非常简单,首先我们需要看一下Spring中定义的HandlerExceptionResolver接口:


public interface HandlerExceptionResolver {  
    ModelAndView resolveException(  
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);  
  
}  

handler 应该就是 controller ,他定义了一个resolveException方法,我们如果要处理异常的话,需要实现这个接口类,并且实现resolveException方法,在resolveException方法中处理自己的异常逻辑。
例如我设计一个自定义的异常处理类:




/** 
 * 自定义一个异常捕获处理类 
 * @author zhuli 
 * @date 2014-9-3 
 */  
public class MyExceptionResolver implements HandlerExceptionResolver {  
  
    private static final Logger logger = LoggerFactory.getLogger(MyExceptionResolver.class);  
  
    @Override  
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {  
          
        //可以自由处理各种异常逻辑  
        if (ex instanceof org.springframework.web.HttpRequestMethodNotSupportedException) {  
            logger.warn(Logger.ACTION.DEFAULT, "Http Method Error");  
        }  
        return null;  
    }  
  
}  

然后需要将我们的我们自定义的MyExceptionResolver类注入到bean中
<bean id="MyExceptionResolver" class="com.tiantian.xxx.web.handler.MyExceptionResolver"/>  

具体Spring是怎么调用的?我们可以先看下Spring中的doDispatch方法中,有这么一段代码:
catch (ModelAndViewDefiningException ex) {  
    logger.debug("ModelAndViewDefiningException encountered", ex);  
    mv = ex.getModelAndView();  
}  
catch (Exception ex) {  
    Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
    mv = processHandlerException(processedRequest, response, handler, ex);  
    errorView = (mv != null);  
}  

其中processHandlerException方法就是来捕获异常处理的,那么继续看processHandlerException这个方法:


protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,  
        Object handler, Exception ex) throws Exception {  
  
    // Check registered HandlerExceptionResolvers...  
    ModelAndView exMv = null;  
    for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {  
        exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);  
        if (exMv != null) {  
            break;  
        }  
    }  
    if (exMv != null) {  
        if (exMv.isEmpty()) {  
            return null;  
        }  
        // We might still need view name translation for a plain error model...  
        if (!exMv.hasView()) {  
            exMv.setViewName(getDefaultViewName(request));  
        }  
        if (logger.isDebugEnabled()) {  
            logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);  
        }  
        WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());  
        return exMv;  
    }  
  
    throw ex;  
}  

这个方法中的handlerExceptionResolver.resolveException就是用来捕获异常的,并且Spring允许多个自定义的异常类实现。
可以看this.handlerExceptionResolvers方法,跟踪进去


private void initHandlerExceptionResolvers(ApplicationContext context) {  
        this.handlerExceptionResolvers = null;  
  
        if (this.detectAllHandlerExceptionResolvers) {  
            // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.  
            Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils  
                    .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);  
            if (!matchingBeans.isEmpty()) {  
                this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());  
                // We keep HandlerExceptionResolvers in sorted order.  
                OrderComparator.sort(this.handlerExceptionResolvers);  
            }  
        }  
        else {  
            try {  
                HandlerExceptionResolver her =  
                        context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);  
                this.handlerExceptionResolvers = Collections.singletonList(her);  
            }  
            catch (NoSuchBeanDefinitionException ex) {  
                // Ignore, no HandlerExceptionResolver is fine too.  
            }  
        }  
  
        // Ensure we have at least some HandlerExceptionResolvers, by registering  
        // default HandlerExceptionResolvers if no other resolvers are found.  
        if (this.handlerExceptionResolvers == null) {  
            this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);  
            if (logger.isDebugEnabled()) {  
                logger.debug("No HandlerExceptionResolvers found in servlet '" + getServletName() + "': using default");  
            }  
        }  
    }  

可以清洗看到这个方法是将handlerExceptionResolvers进行了初始化,并将自定义的异常处理类(可以多个)写入this.handlerExceptionResolvers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值