webwork拦截器interceptor 之 ActionInvocation 意义
“将Web页面中的输入元素封装为一个(请求)数据对象”,这个对象就是ActionInvocation类型.
对于Xwork 而言,前端的Webwork 组件为其提供的是一个Map 类型的数据结构。而Action面向的却是Model对象所提供的数据结构。在何时、何处对这两种不同的数据结构进行转换?
写一个辅助类完成这样的工作,并在每次Action 调用之前由框架代码调用他完成转换工作。
Xwork 通过Interceptor 实现了这一步骤,从而我们可以根据需要,灵活的配置所需的Interceptor。从而为Action提供可扩展的预处理、后处理过程。
ActionInvocation 是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。
ActionInvocation 是一个接口, 而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。
Interceptor 的调度流程大致如下:
1. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。
参见ActionInvocation.init方法中相关代码:
Java代码
1. private void init() throws Exception ...{
2. ……
3. List interceptorList = new
4. ArrayList(proxy.getConfig().getInterceptors());
5. interceptors = interceptorList.iterator();
6. }
private void init() throws Exception ...{
……
List interceptorList = new
ArrayList(proxy.getConfig().getInterceptors());
interceptors = interceptorList.iterator();
}
2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor:
下面是DefaultActionInvocation中Action调度代码:
Java代码
1. public String invoke() throws Exception ...{
2. if (executed)
3. throw new IllegalStateException("Action has already executed");
4. if (interceptors.hasNext()) ...{
5. Interceptor interceptor = (Interceptor) interceptors.next();
6. resultCode = interceptor.intercept(this);
7. } else
8. resultCode = invokeAction(getAction(), proxy.getConfig());
9. if (!executed) ...{
10. if (preResultListeners != null) ...{
11. Iterator iterator = preResultListeners.iterator();
12. while (iterator.hasNext()) ...{
13. PreResultListener listener
14. = (PreResultListener) iterator.next();
15. listener.beforeResult(this, resultCode);
16. }
17. }
18. if (proxy.getExecuteResult())
19. executeResult();
20. executed = true;
21. }
22. return resultCode;
23. }
public String invoke() throws Exception ...{
if (executed)
throw new IllegalStateException("Action has already executed");
if (interceptors.hasNext()) ...{
Interceptor interceptor = (Interceptor) interceptors.next();
resultCode = interceptor.intercept(this);
} else
resultCode = invokeAction(getAction(), proxy.getConfig());
if (!executed) ...{
if (preResultListeners != null) ...{
Iterator iterator = preResultListeners.iterator();
while (iterator.hasNext()) ...{
PreResultListener listener
= (PreResultListener) iterator.next();
listener.beforeResult(this, resultCode);
}
}
if (proxy.getExecuteResult())
executeResult();
executed = true;
}
return resultCode;
}
所有的拦截器都必须实现Interceptor 接口。
public interface Interceptor {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
在Interceptor 实现中,抽象实现AroundInterceptor得到了最广泛的应用(扩展),它增加了预处理(before)和后处理(after)方法的定义。
AroundInterceptor.java:
Java代码
1. public abstract class AroundInterceptor implements Interceptor
2. ...{
3. protected Log log = LogFactory.getLog(this.getClass());
4.
5. public void destroy() ...{
6. }
7.
8. public void init() ...{
9. }
10.
11. public String intercept(ActionInvocation invocation) throws Exception ...{
12. String result = null;
13. before(invocation);
14. result = invocation.invoke();
15. after(invocation, result);
16. return result;
17. }
18.
19. protected abstract void after
20. (ActionInvocation actioninvocation, String string) throws Exception;
21.
22. protected abstract void before(ActionInvocation actioninvocation)
23. throws Exception;
24. }
public abstract class AroundInterceptor implements Interceptor
...{
protected Log log = LogFactory.getLog(this.getClass());
public void destroy() ...{
}
public void init() ...{
}
public String intercept(ActionInvocation invocation) throws Exception ...{
String result = null;
before(invocation);
result = invocation.invoke();
after(invocation, result);
return result;
}
protected abstract void after
(ActionInvocation actioninvocation, String string) throws Exception;
protected abstract void before(ActionInvocation actioninvocation)
throws Exception;
}
AroundInterceptor.invoke 方法中,调用了参数invocation的invoke 方法。
最后,结合最常用的ParametersInterceptor,看看Xwork 是如何通过Interceptor,将Webwork传入的Map类型数据结构,转换为Action所需的Java 模型对象。
ParametersInterceptor.java:
Java代码
1. public class ParametersInterceptor extends AroundInterceptor ...{
2. protected void after(ActionInvocation dispatcher, String result)
3. throws Exception ...{
4. }
5. protected void before(ActionInvocation invocation) throws Exception
6. ...{
7. if (!(invocation.getAction() instanceof NoParameters)) ...{
8. final Map parameters =
9. ActionContext.getContext().getParameters(); ⑴
10. if (log.isDebugEnabled()) ...{
11. log.debug("Setting params " + parameters);
12. }
13. ActionContext invocationContext =
14. invocation.getInvocationContext();
15. try ...{
16. invocationContext.put(
17. InstantiatingNullHandler.CREATE_NULL_OBJECTS,
18. Boolean.TRUE);
19. invocationContext.put(
20. XWorkMethodAccessor.DENY_METHOD_EXECUTION,
21. Boolean.TRUE);
22. invocationContext.put(
23. XWorkConverter.REPORT_CONVERSION_ERRORS,
24. Boolean.TRUE);
25. if (parameters != null) ...{
26. final OgnlValueStack stack =
27. ActionContext.getContext().getValueStack(); ⑵
28. for (Iterator iterator =parameters.entrySet().iterator();
29. iterator.hasNext();
30. ) ...{
31. Map.Entry entry = (Map.Entry) iterator.next();
32. stack.setValue( ⑷
33. entry.getKey().toString(),
34. entry.getValue());
35. }
36. }
37. } finally ...{
38. invocationContext.put(
39. InstantiatingNullHandler.CREATE_NULL_OBJECTS,
40. Boolean.FALSE);
41. invocationContext.put(
42. XWorkMethodAccessor.DENY_METHOD_EXECUTION,
43. Boolean.FALSE);
44. invocationContext.put(
45. XWorkConverter.REPORT_CONVERSION_ERRORS,
46. Boolean.FALSE);
47. }
48. }
49. }
50. }
public class ParametersInterceptor extends AroundInterceptor ...{
protected void after(ActionInvocation dispatcher, String result)
throws Exception ...{
}
protected void before(ActionInvocation invocation) throws Exception
...{
if (!(invocation.getAction() instanceof NoParameters)) ...{
final Map parameters =
ActionContext.getContext().getParameters(); ⑴
if (log.isDebugEnabled()) ...{
log.debug("Setting params " + parameters);
}
ActionContext invocationContext =
invocation.getInvocationContext();
try ...{
invocationContext.put(
InstantiatingNullHandler.CREATE_NULL_OBJECTS,
Boolean.TRUE);
invocationContext.put(
XWorkMethodAccessor.DENY_METHOD_EXECUTION,
Boolean.TRUE);
invocationContext.put(
XWorkConverter.REPORT_CONVERSION_ERRORS,
Boolean.TRUE);
if (parameters != null) ...{
final OgnlValueStack stack =
ActionContext.getContext().getValueStack(); ⑵
for (Iterator iterator =parameters.entrySet().iterator();
iterator.hasNext();
) ...{
Map.Entry entry = (Map.Entry) iterator.next();
stack.setValue( ⑷
entry.getKey().toString(),
entry.getValue());
}
}
} finally ...{
invocationContext.put(
InstantiatingNullHandler.CREATE_NULL_OBJECTS,
Boolean.FALSE);
invocationContext.put(
XWorkMethodAccessor.DENY_METHOD_EXECUTION,
Boolean.FALSE);
invocationContext.put(
XWorkConverter.REPORT_CONVERSION_ERRORS,
Boolean.FALSE);
}
}
}
}
ParametersInterceptor 扩展了抽象类AroundInterceptor。并在其预处理方法(before)中实现了数据的转换。
数据转换的过程并不复杂:
⑴ 首先由ActionContext获得Map型的参数集parameters。
⑵ 由ActionContext获得值栈(OgnlValueStack)。
⑶ 遍历parameters中的各项数据。
⑷ 通过OgnlValueStack,根据数据的键值,为Model 对象填充属性数据。
OgnlValueStack 是http://www.ognl.org4提供的一套可读写对象属性的类库
上面的代码中并没有发现将Model对象入栈的部分,是由于ActionInvocation在初始化的时候已经预先完成了压栈工作,如DefaultActionInvocation.init方法中代码所示:
private void init() throws Exception {
Map contextMap = createContextMap();
createAction();
if (pushAction) {
stack.push(action); //压栈
}
……
}
旁白:Servlet 2.3规范中引入的Filter 算是拦截器的一个典型实现,它在Servlet执行之前被触发,对输入参数进行处理之后,再将工作流程传递给对应的Servlet。
分享到:
相关推荐
本篇将详细介绍WebWork中的核心概念——拦截器(Interceptor)以及验证(Validation)机制,并结合提供的帮助文档进行学习指导。 首先,我们来理解WebWork的拦截器机制。在WebWork中,拦截器是处理请求的关键组件,...
接口中有三个方法:`void init()`用于初始化,`String intercept(ActionInvocation invocation) throws Exception`是拦截器的主要工作方法,`void destroy()`则在拦截器不再使用时调用。 ### 4. 配置拦截器 在...
`ActionInvocation`接口及其实现类则表示动作的执行链,它可以支持拦截器的介入,提供事务管理、权限控制等功能。 2. **模型-视图-控制器模式** MVC模式在XWork中得到了充分的体现。`Action`类代表了模型层,处理...
3. ActionInvocation负责调用Action的方法,并可以插入拦截器链进行预处理。 4. Action执行业务逻辑,将结果存储在ValueStack中。 5. 结果处理器(Result)根据Action返回的结果类型,决定如何展示给用户,如转发到...
WebWork引入了拦截器(Interceptor)的概念,它在动作执行前后执行自定义逻辑。拦截器可以用于事务管理、权限检查、日志记录等多种用途,极大地增强了框架的灵活性和扩展性。 ### 5. 动态方法调用 WebWork支持动态...
而ActionInvocation则表示Action的执行状态,它包含了Action实例以及所有Interceptor(拦截器)。拦截器允许开发者在Action执行前后插入自定义逻辑,实现了面向切面的编程(AOP),提高了代码的复用性和解耦性。 ...
- **拦截器(Interceptor)**:拦截器实现了`com.opensymphony.xwork.interceptor.Interceptor`接口,它们在Action执行前后进行方法的织入通知。拦截器可以实现诸如防止表单重复提交等功能。 - **Action执行**:通过...
- 在`invoke`过程中,ActionInvocation会根据Action配置的拦截器链(Interceptor Chain)执行拦截器,这些拦截器可以用来做权限检查、日志记录等预处理或后处理工作。 - 最后,Action的执行结果会被转换成对应的...
ActionInvocation则表示Action的执行状态,它持有着Action实例和一系列Interceptor(拦截器)。拦截器是AOP(面向切面编程)的一种实现,允许在Action执行前后插入自定义的逻辑,提高了代码的可复用性和解耦性。 ...
ActionInvocation则表示Action执行的状态,它包含了Action实例和一系列Interceptor(拦截器)。拦截器是AOP(面向切面编程)的一种实现,允许在Action执行前后插入自定义逻辑,从而实现了解耦和模块化的设计。 在...
- 拦截器(Interceptor):位于中间层,执行Action执行前后的一些通用功能。 - Action:位于最后端,作为业务控制器,由开发者编写,实现业务逻辑、操作数据库并返回结果视图。 4. Struts2包的默认拦截器设置 ...
WebWork支持拦截器(Interceptor)、类型安全的参数绑定、强大的表单处理以及AOP(面向切面编程)特性,从而提高了开发效率和代码质量。 **WebWork安装 - HelloWorld** 安装WebWork通常包括以下几个步骤: 1. 获取...
它的核心是基于WebWork框架,提供了丰富的功能和灵活性,包括强大的动作映射、拦截器机制、强大的视图组件以及灵活的配置选项。 **Struts2工作原理** 1. **请求处理流程** 当一个HTTP请求到达服务器时,它首先...
以上只是WebWork教程的部分内容,完整的学习笔记涵盖了更多高级主题,如Interceptor(拦截器)、Validation(验证)、I18N(国际化)、AOP支持以及与其他开源项目的集成,如G-Roller-WW和Spring等。通过深入学习和...
Struts.2采用了更为灵活的拦截器(Interceptor)机制来处理请求,支持多种视图技术(如JSP、Velocity、FreeMarker等),并提供了丰富的插件生态系统,使得开发者可以轻松地扩展框架功能。同时,Struts.2与WebWork...
4. **拦截器(Interceptor)**:拦截器是Struts2的核心组件之一,它们实现了`com.opensymphony.xwork.interceptor.Interceptor`接口。在请求到达Action之前,拦截器会按照配置顺序执行,进行方法前的织入通知。在响应...
通过源码阅读,我们可以了解ActionInvocation如何根据配置的拦截器顺序逐个执行,并如何在每个拦截器中注入业务逻辑。 Webwork是Struts2的前身,它的许多设计理念和机制被继承到了Struts2中。Webwork的核心概念包括...
拦截器是Struts2的核心特性之一,它允许开发者在Action执行前后插入自定义逻辑。拦截器按照栈的顺序依次执行,可以用于登录验证、日志记录、性能监控等多种场景。例如,`Interceptor_Simulation`可能就是模拟了一个...