Struts2默认拦截器(ExceptionMappingInterceptor)的使用及源码阅读

定义

捕获异常并定位到指定视图。
ps:从这给类的原型,可以帮助我们思考异常如何以日志形式记录,可以再此类的基础上进行扩展。这个待日后有慢慢琢磨。

使用

1.局部exception配置使用

Action源码:
[java]  view plain copy print ?
  1. public class SourceCoreAction {  
  2.    
  3.     public String error() throws ClassNotFoundException {  
  4.         System.out.println("do the error!");      
  5.         Class.forName("xxx");         
  6.         return "success";  
  7.     }  
  8.       
  9.  }  
struts-xxx.xml配置:
[html]  view plain copy print ?
  1. <span style="white-space:pre">      </span><action name="error" class="com.company.strutstudy.web.action.core.SourceCoreAction"  
  2.             method="error">  
  3.             <interceptor-ref name="exception"></interceptor-ref><!--只有一个默认拦截器起作用,好debug-->  
  4.             <result name="input">/core/exception.jsp</result>  
  5.             <result name="success">/core/ok.jsp</result>  
  6.             <exception-mapping result="input" exception="java.lang.Exception"></exception-mapping>  
  7.         </action>  

2.全局exception配置使用

Action源码不变,参考局部exception

struts-xxx.xml配置:
[html]  view plain copy print ?
  1. <struts>  
  2.     <package name="exception" extends="struts-default" abstract="true">  
  3.         <global-results>  
  4.             <result name="input">/core/exception.jsp</result>  
  5.         </global-results>  
  6.         <global-exception-mappings>  
  7.             <exception-mapping result="input" exception="java.lang.Exception"></exception-mapping>  
  8.         </global-exception-mappings>  
  9.     </package>  
  10.     <package name="core" extends="exception">  
  11.         <action name="error"class="com.company.strutstudy.web.action.core.SourceCoreAction" method="error">  
  12.             <interceptor-ref name="exception"></interceptor-ref>  
  13.             <result name="success">/core/ok.jsp</result>  
  14.         </action>  
  15.     </package>  
  16.  </struts>  

源码阅读

[java]  view plain copy print ?
  1. public class ExceptionMappingInterceptor extends AbstractInterceptor {  
  2.        
  3.      protected static final Log log = LogFactory.getLog(ExceptionMappingInterceptor.class);  
  4.      protected Log categoryLogger;  
  5.      protected boolean logEnabled = false;  
  6.      protected String logCategory;  
  7.      protected String logLevel;      
  8.    
  9.      ....getset省略  
  10.      public String intercept(ActionInvocation invocation) throws Exception {  
  11.          String result;  
  12.          /* 
  13.           * 处理action或拦截器执行的异常 
  14.           */  
  15.          try {  
  16.              result = invocation.invoke();  
  17.          } catch (Exception e) {  
  18.             //默认为false  
  19.              if (logEnabled) {  
  20.                  handleLogging(e);  
  21.              }  
  22.              //获取全局或局部与该action相关的exception映射信息  
  23.              List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();  
  24.              //获取异常发生以后的逻辑视图(resultcode)  
  25.              String mappedResult = this.findResultFromExceptions(exceptionMappings, e);  
  26.              if (mappedResult != null) {  
  27.                  result = mappedResult;  
  28.                  //将异常信息压入栈顶,异常信息可在页面通过ognl进行获取。  
  29.                  publishException(invocation, new ExceptionHolder(e));  
  30.              } else {  
  31.                  throw e;  
  32.              }  
  33.          }  
  34.    
  35.          return result;  
  36.      }  
  37.    
  38.      /** 
  39.       * Handles the logging of the exception. 
  40.       *  
  41.       * @param e  the exception to log. 
  42.       */  
  43.      protected void handleLogging(Exception e) {  
  44.         if (logCategory != null) {  
  45.             if (categoryLogger == null) {  
  46.                 // init category logger  
  47.                 categoryLogger = LogFactory.getLog(logCategory);  
  48.             }  
  49.             doLog(categoryLogger, e);  
  50.         } else {  
  51.             doLog(log, e);  
  52.         }  
  53.      }  
  54.        
  55.      /** 
  56.       * Performs the actual logging. 
  57.       *  
  58.       * @param logger  the provided logger to use. 
  59.       * @param e  the exception to log. 
  60.       */  
  61.      protected void doLog(Log logger, Exception e) {  
  62.         if (logLevel == null) {  
  63.             logger.debug(e.getMessage(), e);  
  64.             return;  
  65.         }     
  66.         if ("trace".equalsIgnoreCase(logLevel)) {  
  67.             logger.trace(e.getMessage(), e);  
  68.         } else if ("debug".equalsIgnoreCase(logLevel)) {  
  69.             logger.debug(e.getMessage(), e);  
  70.         } else if ("info".equalsIgnoreCase(logLevel)) {  
  71.             logger.info(e.getMessage(), e);  
  72.         } else if ("warn".equalsIgnoreCase(logLevel)) {  
  73.             logger.warn(e.getMessage(), e);  
  74.         } else if ("error".equalsIgnoreCase(logLevel)) {  
  75.             logger.error(e.getMessage(), e);  
  76.         } else if ("fatal".equalsIgnoreCase(logLevel)) {  
  77.             logger.fatal(e.getMessage(), e);  
  78.         } else {  
  79.             throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported");  
  80.         }  
  81.      }  
  82.    
  83.      private String findResultFromExceptions(List exceptionMappings, Throwable t) {  
  84.          String result = null;  
  85.    
  86.          // Check for specific exception mappings.  
  87.          if (exceptionMappings != null) {  
  88.              int deepest = Integer.MAX_VALUE;  
  89.              for (Iterator iter = exceptionMappings.iterator(); iter.hasNext();) {  
  90.                  ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) iter.next();  
  91.                  int depth = getDepth(exceptionMappingConfig.getExceptionClassName(), t);  
  92.                  if (depth >= 0 && depth < deepest) {  
  93.                      deepest = depth;  
  94.                      result = exceptionMappingConfig.getResult();  
  95.                  }  
  96.              }  
  97.          }  
  98.    
  99.          return result;  
  100.      }  
  101.    
  102.      /** 
  103.       * Return the depth to the superclass matching. 0 means ex matches exactly. Returns -1 if there's no match. 
  104.       * Otherwise, returns depth. Lowest depth wins. 
  105.       * 
  106.       * @param exceptionMapping  the mapping classname 
  107.       * @param t  the cause 
  108.       * @return the depth, if not found -1 is returned. 
  109.       */  
  110.      public int getDepth(String exceptionMapping, Throwable t) {  
  111.          return getDepth(exceptionMapping, t.getClass(), 0);  
  112.      }  
  113.    
  114.      private int getDepth(String exceptionMapping, Class exceptionClass, int depth) {  
  115.          if (exceptionClass.getName().indexOf(exceptionMapping) != -1) {  
  116.              // Found it!  
  117.              return depth;  
  118.          }  
  119.          // If we've gone as far as we can go and haven't found it...  
  120.          if (exceptionClass.equals(Throwable.class)) {  
  121.              return -1;  
  122.          }  
  123.          return getDepth(exceptionMapping, exceptionClass.getSuperclass(), depth + 1);  
  124.      }  
  125.    
  126.      /** 
  127.       * Default implementation to handle ExceptionHolder publishing. Pushes given ExceptionHolder on the stack. 
  128.       * Subclasses may override this to customize publishing. 
  129.       * 
  130.       * @param invocation The invocation to publish Exception for. 
  131.       * @param exceptionHolder The exceptionHolder wrapping the Exception to publish. 
  132.       */  
  133.      protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {  
  134.          invocation.getStack().push(exceptionHolder);  
  135.      }  
  136.  }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值