struts2 PreResultListener兑现回调
开发interceptor的时候,了解action已经执行完毕而result还没有开始执行的时间点往往很重要的。譬如在异常处理方面就是如
此:在action处理的过程中,由于后台的处理,出现的异常很可能是系统异常;而在result处理的过程中,异常则可能出现在为用户呈现的页面的时
候,而不是由于系统问题。
下面给出了ExceptionInterceptor的代码,该interceptor会在result开始执行之前与
之后以不同的方式处理异常。在result开始执行之前,可以改变用于从action配置中查询result的返回码,而在webwork应用程序中,使
用Action.ERROR是一个常用的实践技巧:将Action.ERROR映射至向用户提示错误的页面。所以,需要捕获异常并返回
Action.ERROR。在result开始执行之后,来自interceptor的返回码就不再那样重要了,但是仍然可以获得由
beforeResult()方法回传给result
code,并且可以返回它。在以下离子中需要注意的一点是:由于interceptor必须是无状态的,因此它为每一个ActionInvocation
创建一个新的ExceptionHandler,可以保存该ActionInvocation的状态。
ExceptionInterceptor:在result前后以不同的方式处理异常
开发interceptor的时候,了解action已经执行完毕而result还没有开始执行的时间点往往很重要的。譬如在异常处理方面就是如此:在action处理的过程中,由于后台的处理,出现的异常很可能是系统异常;而在result处理的过程中,异常则可能出现在为用户呈现的页面的时候,而不是由于系统问题。
下面给出了ExceptionInterceptor的代码,该interceptor会在result开始执行之前与之后以不同的方式处理异常。在result开始执行之前,可以改变用于从action配置中查询result的返回码,而在webwork应用程序中,使用Action.ERROR是一个常用的实践技巧:将Action.ERROR映射至向用户提示错误的页面。所以,需要捕获异常并返回 Action.ERROR。在result开始执行之后,来自interceptor的返回码就不再那样重要了,但是仍然可以获得由 beforeResult()方法回传给result code,并且可以返回它。在以下离子中需要注意的一点是:由于interceptor必须是无状态的,因此它为每一个ActionInvocation 创建一个新的ExceptionHandler,可以保存该ActionInvocation的状态。
ExceptionInterceptor:在result前后以不同的方式处理异常
/**
* @filename ExceptionInterceptor.java
* @author Rain_zhou
* @version ExceptionInterceptor,下午01:05:50
*/
package com.founder.study.forum.interceptor;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.Interceptor;
/**
* @author Rain_zhou
*
*/
public class ExceptionInterceptor implements Interceptor {
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.Interceptor#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.Interceptor#init()
*/
public void init() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.Interceptor#intercept(com.opensymphony.xwork.ActionInvocation)
*/
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
ExceptionHandler handler=new ExceptionHandler(arg0);
return handler.invoke();
}
}
/**
* @filename ExceptionHandler.java
* @author Rain_zhou
* @version ExceptionHandler,下午01:07:04
*/
package com.founder.study.forum.interceptor;
import com.founder.study.forum.helper.NoLimitException;
import com.opensymphony.xwork.Action;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.PreResultListener;
/**
* @author Rain_zhou
*
*/
public class ExceptionHandler implements PreResultListener {
private ActionInvocation invocation;
private boolean beforeResult=true;
private String result=Action.ERROR;
public ExceptionHandler(ActionInvocation invocation){
this.invocation=invocation;
invocation.addPreResultListener(this);
}
String invoke(){
try{
result=invocation.invoke();
}catch(Exception e){
if(beforeResult){
return Action.ERROR;
}else{
return result;
}
}
return result;
}
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.PreResultListener#beforeResult(com.opensymphony.xwork.ActionInvocation, Java.lang.String)
*/
public void beforeResult(ActionInvocation arg0, String arg1) {
// TODO Auto-generated method stub
beforeResult=false;
result=arg1;
}
}
1.主要功能&触发时间
该监听器主要在action的execute方法执行完以后,result.execute()方法执行前调用。
接口如下
- public interface PreResultListener {
- void beforeResult(ActionInvocation invocation, String resultCode);
- }
在DefaultActionInvocation对应的调用如下
1. //判断是否还有拦截器未执行,如果还有则继续执行拦截器链
2. //这里通过把DefaultActionInvocation对象本身往后续拦截器中传递来实现interceptors这个interceptor的迭代。
3. if (interceptors.hasNext()) {
4. final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
5. UtilTimerStack.profile("interceptor: "+interceptor.getName(),
6. new UtilTimerStack.ProfilingBlock<String>() {
7. public String doProfiling() throws Exception {
8. resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
9. return null;
10. }
11. });
12. } else {
13. //所有拦截器执行完成调用action的执行方法。
14. resultCode = invokeActionOnly();
15. }
16.
17. // this is needed because the result will be executed, then control will return to the Interceptor, which will
18. // return above and flow through again
19. //调用preResultListeners的内容
20. if (!executed) {
21. if (preResultListeners != null) {
22. for (Iterator iterator = preResultListeners.iterator();
23. iterator.hasNext();) {
24. PreResultListener listener = (PreResultListener) iterator.next();
25.
26. String _profileKey="preResultListener: ";
27. try {
28. UtilTimerStack.push(_profileKey);
29. listener.beforeResult(this, resultCode);
30. }
31. finally {
32. UtilTimerStack.pop(_profileKey);
33. }
34. }
35. }
36.
37. // now execute the result, if we're supposed to
38. //调用result.execute方法.
39. if (proxy.getExecuteResult()) {
40. executeResult();
41. }
42.
43. executed = true;
44. }
2.注册方法
通过调用 invocation.addPreResultListener具体代码如下(摘自struts2 docs)
- public class MyAction extends ActionSupport {
- ...
- public String execute() throws Exception {
- ActionInvocation invocation = ActionContext.getActionInvocation();
- invocation.addPreResultListener(new PreResultListener() {
- public void beforeResult(ActionInvocation invocation,
- String resultCode) {
- // perform operation necessary before Result execution
- }
- });
- }
- ...
-
}