在struts2的struts-default.xml中定义了一个name为exception拦截器,实现类是com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor,它的作用是对action中的异常进行处理(输出异常日志,与配置文件中的<exception-mapping/>匹配).
该拦截器有三个参数,分别是:
a、logEnabled (可选) -是否将异常信息打印到日志中,默认为false
b、logLevel (可选) - 打印异常的日志级别,可选(trace, debug, info, warn, error, fatal),默认是debug
c、logCategory (可选) - 指定logger的种类,默认使用"com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"
首先说明一下 struts.xml 中的<exception-mapping/>配置。
<exception-mapping/> 是将异常类型与result进行对应,该元素需要指定两个属性:1,exception:此属性指定该异常映射所设置的异常类型。 2,result:此属性指定Action出现该异常时,系统转入result属性所指向的结果。 而 <exception-mapping/>也分为两种:1,局部异常映射:﹤exception-mapping/﹥元素作为﹤action/﹥元素的子元素配置。2,全局异常映射:﹤exception-mapping/﹥元素作为﹤global-exception-mappings/>元素的子元素配置。
例如:
<package name="test_Alias" extends="struts-default" namespace="/alias">
<global-exception-mappings>
<exception-mapping result="input" exception="java.lang.Exception"/>
</global-exception-mappings>
<action name="from" class="com.warning.interceptor.action.AliasAction1" method="_name">
<result name="success" type="chain">to</result>
<exception-mapping result="input" exception="java.lang.RuntimeException"/>
</action>
</package>
使用Struts2的标签来输出异常信息:
<s:property value="exception"/>:输出异常对象本身。
<s:property value="exceptionStack"/>: 输出异常堆栈信息。
由于exception拦截器已经在默认拦截器栈defaultStack中,所以无需进行配置。
接下来我们看一下exception拦截器都做了什么事情:
public String intercept(ActionInvocation invocation) throws Exception {
String result;
try {
//先执行action,如果action中抛出异常,进入catch块,没有异常直接返回
result = invocation.invoke();
} catch (Exception e) {
//isLogEnabled()的返回值如果是true,这进入handleLogging()方法,打印异常信息。handleLogging的值在初始化拦截器时候指定,默认为false
if (isLogEnabled()) {
handleLogging(e);
}
//获取action中所有的<exception-mapping>配置
List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
//执行findResultFromExceptions()方法,返回异常信息对应的result
String mappedResult = this.findResultFromExceptions(exceptionMappings, e);
if (mappedResult != null) {
result = mappedResult;
//利用异常对象构建一个ExceptionHolder对象,然后push到值栈的顶部,该方法调用的是invocation.getStack().push(exceptionHolder);ExceptionHolder类中存在两个方法:getException()返回异常对象本省、getExceptionStack()方法调用e.printStackTrace()方法把异常栈信息出入到一个PrintWriter流中,然后从流中获取到一个字符串返回(该字符串和调用e.printStackTrace()后控制台输出的错误信息一样),这就是为什么可以使用<s:property value="exception"/>和 <s:property value="exceptionStack"/>获取到异常信息了。
publishException(invocation, new ExceptionHolder(e));
} else {
throw e;
}
}
return result;
}
接下来我们分别看一下handleLogging方法和findResultFromExceptions方法分别做了些什么事情:
protected void handleLogging(Exception e) {
if (logCategory != null) {
//如果配置了logCategory参数,则根据参数初始化logger
if (categoryLogger == null) {
// init category logger
categoryLogger = LoggerFactory.getLogger(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(Logger logger, Exception e) {
//如果配置了logEnabled参数与为true,但未配置logLevel 参数,则使用logger.debug()方法打印日志(这样的效果像logLevel 的默认值为debug)。
if (logLevel == null) {
logger.debug(e.getMessage(), e);
return;
}
//根据logLevel参数调用不通方法打印日志。
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");
}
}
protected String findResultFromExceptions(List<ExceptionMappingConfig> exceptionMappings, Throwable t) {
String result = null;
//寻找exceptionMappings中与异常最匹配的result
if (exceptionMappings != null) {
int deepest = Integer.MAX_VALUE;
for (Object exceptionMapping : exceptionMappings) {
ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) exceptionMapping;
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().contains(exceptionMapping)) {
// 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);
}
handleLogging方法打印日志,findResultFromExceptions方法从配置中寻找与异常最匹配的result返回。
版权所有,转载请标明出处:http://blogwarning.iteye.com/blog/1334947
分享到:
相关推荐
Struts2拦截器(Interceptor) Struts2拦截器(Interceptor)
Struts2默认拦截器解析.pdf
解决Struts2中的中文乱码。该代码是用作Struts2的拦截器中
struts2常用拦截器,struts2经常用到的拦截器,熟悉熟悉
Struts2默认拦截器解析[归类].pdf
该例子为struts2注解与拦截器demo,利用myEclipse8.5开发,导入刚才后,自动加载所需struts2的jar包,可以直接运行,是初学struts2注解、拦截器很好的例子,保证10分钟学会2种技术,愿意分享给大家。
NULL 博文链接:https://blogwarning.iteye.com/blog/1390172
struts2 Interceptor拦截器 http://whitewolf.0fees.net
使用Struts2实现用户权限拦截、重点是掌握拦截器的使用和配置方法,通过案例的学习,就能掌握struts中拦截器的使用方法,让我们能快速上手
Struts2拦截器.ppt Struts2拦截器.ppt Struts2拦截器.ppt
关于struts2 拦截器的详细的解释及其在开发中对struts2的拦截器的应用和拦截器在框架中的作用.
Struts2拦截器源程序 Struts2拦截器源程序 Struts2拦截器源程序 Struts2拦截器源程序 Struts2拦截器源程序
详细说明了struts2中拦截器的使用。并且通过一个小例子讲解了拦截器的具体使用
struts2,Interceptor struts2拦截器实例,两套实例,一套是针对单个的action配置的,另一套实例是针对全局的action配置的拦截器interceptor
struts2 用拦截器 实现用户权限登录 可以直接运行,只单单用到struts的东西。
基于struts2的拦截器测试,实现了页面的跳转,中间过程的拦截
struts2拦截器应用小例子,与大家共分享
Struts2拦截器实现权限控制demo,我感觉对初学者还是有一定帮助的
Struts2的拦截器的使用详解实例 博文链接:https://zmx.iteye.com/blog/457434
Struts2的核心,拦截器的应用!!!