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

本文详细介绍了Struts2框架中ExceptionMappingInterceptor的使用,包括局部和全局exception配置的两种方式,并深入探讨了其内部源码,帮助读者理解异常处理的实现机制。
摘要由CSDN通过智能技术生成

定义

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

使用

1.局部exception配置使用

Action源码:
public class SourceCoreAction {
 
 	public String error() throws ClassNotFoundException {
 		System.out.println("do the error!");	
 		Class.forName("xxx");		
 		return "success";
 	}
 	
 }
struts-xxx.xml配置:
		<action name="error" class="com.company.strutstudy.web.action.core.SourceCoreAction"
 			method="error">
 			<interceptor-ref name="exception"></interceptor-ref><!--只有一个默认拦截器起作用,好debug-->
 			<result name="input">/core/exception.jsp</result>
 			<result name="success">/core/ok.jsp</result>
 			<exception-mapping result="input" exception="java.lang.Exception"></exception-mapping>
 		</action>

2.全局exception配置使用

Action源码不变,参考局部exception

struts-xxx.xml配置:
<struts>
 	<package name="exception" extends="struts-default" abstract="true">
 		<global-results>
 			<result name="input">/core/exception.jsp</result>
 		</global-results>
 		<global-exception-mappings>
 			<exception-mapping result="input" exception="java.lang.Exception"></exception-mapping>
 		</global-exception-mappings>
 	</package>
 	<package name="core" extends="exception">
 		<action name="error"class="com.company.strutstudy.web.action.core.SourceCoreAction" method="error">
 			<interceptor-ref name="exception"></interceptor-ref>
 			<result name="success">/core/ok.jsp</result>
 		</action>
 	</package>
 </struts>

源码阅读

public class ExceptionMappingInterceptor extends AbstractInterceptor {
     
     protected static final Log log = LogFactory.getLog(ExceptionMappingInterceptor.class);
     protected Log categoryLogger;
     protected boolean logEnabled = false;
     protected String logCategory;
     protected String logLevel;    
 
     ....getset省略
     public String intercept(ActionInvocation invocation) throws Exception {
         String result;
         /*
          * 处理action或拦截器执行的异常
          */
         try {
             result = invocation.invoke();
         } catch (Exception e) {
         	//默认为false
             if (logEnabled) {
                 handleLogging(e);
             }
             //获取全局或局部与该action相关的exception映射信息
             List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
             //获取异常发生以后的逻辑视图(resultcode)
             String mappedResult = this.findResultFromExceptions(exceptionMappings, e);
             if (mappedResult != null) {
                 result = mappedResult;
                 //将异常信息压入栈顶,异常信息可在页面通过ognl进行获取。
                 publishException(invocation, new ExceptionHolder(e));
             } else {
                 throw e;
             }
         }
 
         return result;
     }
 
     /**
      * Handles the logging of the exception.
      * 
      * @param e  the exception to log.
      */
     protected void handleLogging(Exception e) {
     	if (logCategory != null) {
         	if (categoryLogger == null) {
         		// init category logger
         		categoryLogger = LogFactory.getLog(logCategory);
         	}
         	doLog(categoryLogger, e);
     	} else {
     		doLog(log, e);
     	}
     }
     
     /**
      * Performs the actual logging.
      * 
      * @param logger  the provided logger to use.
      * @param e  the exception to log.
      */
     protected void doLog(Log logger, Exception e) {
     	if (logLevel == null) {
     		logger.debug(e.getMessage(), e);
     		return;
     	}  	
     	if ("trace".equalsIgnoreCase(logLevel)) {
     		logger.trace(e.getMessage(), e);
     	} else if ("debug".equalsIgnoreCase(logLevel)) {
     		logger.debug(e.getMessage(), e);
     	} else if ("info".equalsIgnoreCase(logLevel)) {
     		logger.info(e.getMessage(), e);
     	} else if ("warn".equalsIgnoreCase(logLevel)) {
     		logger.warn(e.getMessage(), e);
     	} else if ("error".equalsIgnoreCase(logLevel)) {
     		logger.error(e.getMessage(), e);
     	} else if ("fatal".equalsIgnoreCase(logLevel)) {
     		logger.fatal(e.getMessage(), e);
     	} else {
     		throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported");
     	}
     }
 
     private String findResultFromExceptions(List exceptionMappings, Throwable t) {
         String result = null;
 
         // Check for specific exception mappings.
         if (exceptionMappings != null) {
             int deepest = Integer.MAX_VALUE;
             for (Iterator iter = exceptionMappings.iterator(); iter.hasNext();) {
                 ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) iter.next();
                 int depth = getDepth(exceptionMappingConfig.getExceptionClassName(), t);
                 if (depth >= 0 && depth < deepest) {
                     deepest = depth;
                     result = exceptionMappingConfig.getResult();
                 }
             }
         }
 
         return result;
     }
 
     /**
      * Return the depth to the superclass matching. 0 means ex matches exactly. Returns -1 if there's no match.
      * Otherwise, returns depth. Lowest depth wins.
      *
      * @param exceptionMapping  the mapping classname
      * @param t  the cause
      * @return the depth, if not found -1 is returned.
      */
     public int getDepth(String exceptionMapping, Throwable t) {
         return getDepth(exceptionMapping, t.getClass(), 0);
     }
 
     private int getDepth(String exceptionMapping, Class exceptionClass, int depth) {
         if (exceptionClass.getName().indexOf(exceptionMapping) != -1) {
             // Found it!
             return depth;
         }
         // If we've gone as far as we can go and haven't found it...
         if (exceptionClass.equals(Throwable.class)) {
             return -1;
         }
         return getDepth(exceptionMapping, exceptionClass.getSuperclass(), depth + 1);
     }
 
     /**
      * Default implementation to handle ExceptionHolder publishing. Pushes given ExceptionHolder on the stack.
      * Subclasses may override this to customize publishing.
      *
      * @param invocation The invocation to publish Exception for.
      * @param exceptionHolder The exceptionHolder wrapping the Exception to publish.
      */
     protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
         invocation.getStack().push(exceptionHolder);
     }
 }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值