Spring 异常处理HandlerExceptionResolver

 

Java深入 - Spring 异常处理HandlerExceptionResolver

  19799人阅读  评论(1)  收藏  举报
  分类:

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

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * Interface to be implemented by objects than can resolve exceptions thrown 
  3.  * during handler mapping or execution, in the typical case to error views. 
  4.  * Implementors are typically registered as beans in the application context. 
  5.  * 
  6.  * <p>Error views are analogous to the error page JSPs, but can be used with 
  7.  * any kind of exception including any checked exception, with potentially 
  8.  * fine-granular mappings for specific handlers. 
  9.  * 
  10.  * @author Juergen Hoeller 
  11.  * @since 22.11.2003 
  12.  */  
  13. public interface HandlerExceptionResolver {  
  14.   
  15.     /** 
  16.      * Try to resolve the given exception that got thrown during on handler execution, 
  17.      * returning a ModelAndView that represents a specific error page if appropriate. 
  18.      * <p>The returned ModelAndView may be {@linkplain ModelAndView#isEmpty() empty} 
  19.      * to indicate that the exception has been resolved successfully but that no view 
  20.      * should be rendered, for instance by setting a status code. 
  21.      * @param request current HTTP request 
  22.      * @param response current HTTP response 
  23.      * @param handler the executed handler, or <code>null</code> if none chosen at the 
  24.      * time of the exception (for example, if multipart resolution failed) 
  25.      * @param ex the exception that got thrown during handler execution 
  26.      * @return a corresponding ModelAndView to forward to, 
  27.      * or <code>null</code> for default processing 
  28.      */  
  29.     ModelAndView resolveException(  
  30.             HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);  
  31.   
  32. }  

他定义了一个resolveException方法,我们如果要处理异常的话,需要实现这个接口类,并且实现resolveException方法,在resolveException方法中处理自己的异常逻辑。

例如我设计一个自定义的异常处理类:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 自定义一个异常捕获处理类 
  3.  * @author zhuli 
  4.  * @date 2014-9-3 
  5.  */  
  6. public class MyExceptionResolver implements HandlerExceptionResolver {  
  7.   
  8.     private static final Logger logger = LoggerFactory.getLogger(MyExceptionResolver.class);  
  9.   
  10.     @Override  
  11.     public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {  
  12.           
  13.         //可以自由处理各种异常逻辑  
  14.         if (ex instanceof org.springframework.web.HttpRequestMethodNotSupportedException) {  
  15.             logger.warn(Logger.ACTION.DEFAULT, "Http Method Error");  
  16.         }  
  17.         return null;  
  18.     }  
  19.   
  20. }  

然后需要将我们的我们自定义的MyExceptionResolver类注入到bean中

[html]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. <bean id="MyExceptionResolver" class="com.tiantian.xxx.web.handler.MyExceptionResolver"/>  

具体Spring是怎么调用的?我们可以先看下Spring中的doDispatch方法中,有这么一段代码:

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. catch (ModelAndViewDefiningException ex) {  
  2.     logger.debug("ModelAndViewDefiningException encountered", ex);  
  3.     mv = ex.getModelAndView();  
  4. }  
  5. catch (Exception ex) {  
  6.     Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
  7.     mv = processHandlerException(processedRequest, response, handler, ex);  
  8.     errorView = (mv != null);  
  9. }  

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

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,  
  2.         Object handler, Exception ex) throws Exception {  
  3.   
  4.     // Check registered HandlerExceptionResolvers...  
  5.     ModelAndView exMv = null;  
  6.     for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {  
  7.         exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);  
  8.         if (exMv != null) {  
  9.             break;  
  10.         }  
  11.     }  
  12.     if (exMv != null) {  
  13.         if (exMv.isEmpty()) {  
  14.             return null;  
  15.         }  
  16.         // We might still need view name translation for a plain error model...  
  17.         if (!exMv.hasView()) {  
  18.             exMv.setViewName(getDefaultViewName(request));  
  19.         }  
  20.         if (logger.isDebugEnabled()) {  
  21.             logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);  
  22.         }  
  23.         WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());  
  24.         return exMv;  
  25.     }  
  26.   
  27.     throw ex;  
  28. }  

这个方法中的handlerExceptionResolver.resolveException就是用来捕获异常的,并且Spring允许多个自定义的异常类实现。

可以看this.handlerExceptionResolvers方法,跟踪进去

[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. private void initHandlerExceptionResolvers(ApplicationContext context) {  
  2.         this.handlerExceptionResolvers = null;  
  3.   
  4.         if (this.detectAllHandlerExceptionResolvers) {  
  5.             // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.  
  6.             Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils  
  7.                     .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.classtruefalse);  
  8.             if (!matchingBeans.isEmpty()) {  
  9.                 this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());  
  10.                 // We keep HandlerExceptionResolvers in sorted order.  
  11.                 OrderComparator.sort(this.handlerExceptionResolvers);  
  12.             }  
  13.         }  
  14.         else {  
  15.             try {  
  16.                 HandlerExceptionResolver her =  
  17.                         context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);  
  18.                 this.handlerExceptionResolvers = Collections.singletonList(her);  
  19.             }  
  20.             catch (NoSuchBeanDefinitionException ex) {  
  21.                 // Ignore, no HandlerExceptionResolver is fine too.  
  22.             }  
  23.         }  
  24.   
  25.         // Ensure we have at least some HandlerExceptionResolvers, by registering  
  26.         // default HandlerExceptionResolvers if no other resolvers are found.  
  27.         if (this.handlerExceptionResolvers == null) {  
  28.             this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);  
  29.             if (logger.isDebugEnabled()) {  
  30.                 logger.debug("No HandlerExceptionResolvers found in servlet '" + getServletName() + "': using default");  
  31.             }  
  32.         }  
  33.     }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值