“将Web页面中的输入元素封装为一个(请求)数据对象”,这个对象就是
ActionInvocation
类型.
对于Xwork 而言,前端的Webwork 组件为其提供的是一个Map 类型的数据结构。而Action面向的却是Model对象所提供的数据结构。在何时、何处对这两种不同的数据结构进行转换?
写一个辅助类完成这样的工作,并在每次Action 调用之前由框架代码调用他完成转换工作。
Xwork 通过Interceptor 实现了这一步骤,从而我们可以根据需要,灵活的配置所需的Interceptor。从而为Action提供可扩展的预处理、后处理过程。
ActionInvocation
是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由
ActionInvocation
负责。
ActionInvocation
是一个接口, 而Default
ActionInvocation
则是Webwork 对
ActionInvocation
的默认实现。
Interceptor 的调度流程大致如下:
1.
ActionInvocation
初始化时,根据配置,加载Action相关的所有Interceptor。
参见
ActionInvocation
.init方法中相关代码:
- private
void
init()
throws
Exception ...{
- ……
- List interceptorList = new
- ArrayList(proxy.getConfig().getInterceptors());
- interceptors = interceptorList.iterator();
- }
private void init() throws Exception ...{
……
List interceptorList = new
ArrayList(proxy.getConfig().getInterceptors());
interceptors = interceptorList.iterator();
}
2. 通过
ActionInvocation
.invoke方法调用Action实现时,执行Interceptor:
下面是Default
ActionInvocation
中Action调度代码:
- 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;
- }
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:
- 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;
- }
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:
- 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);
- }
- }
- }
- }
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
在初始化的时候已经预先完成了压栈工作,如Default
ActionInvocation
.init方法中代码所示:
private void init() throws Exception {
Map contextMap = createContextMap();
createAction();
if (pushAction) {
stack.push(action); //压栈
}
……
}
旁白:Servlet 2.3规范中引入的Filter 算是拦截器的一个典型实现,它在Servlet执行之前被触发,对输入参数进行处理之后,再将工作流程传递给对应的Servlet。
相关推荐
07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts 2中实现CRUD 11 Struts 2中的OGNL 12 trus 2的新表单标志的使用 13 Struts 2与AJAX
Struts 2.0系列(MAX),pdf格式,全...Struts 2的基石——拦截器(Interceptor) 在Struts 2中实现IoC 在Struts 2中实现文件上传 在Struts 2中实现CRUD Struts 2中的OGNL Strus 2的新表单标志的使用 Struts 2与AJAX
Struts2.0采用了拦截器(Interceptor)机制,这是一种非常强大的特性,允许开发者在Action执行前后进行一系列操作,如参数填充、验证、事务控制等。拦截器的设计遵循AOP(Aspect Oriented Programming)思想,可以...
接下来,开发者可以根据具体需求进一步深入学习Struts 2.0 的高级特性和最佳实践,例如拦截器(Interceptor)、国际化(i18n)和支持AJAX等功能。Struts 2.0 不仅是一个强大的Web开发工具,而且也是一个学习现代Web...
Struts 2.0 是一个基于MVC设计模式的Java Web框架,它的核心功能之一是拦截器(Interceptor),这是实现业务逻辑控制和增强应用程序功能的重要组件。在Struts 2中,拦截器扮演着中间人的角色,它们在Action调用前后...
Struts2.0通过拦截器(Interceptor)机制实现了动作(Action)的处理,大大提高了代码的可维护性和可复用性。 二、MVC模式 在Struts2.0中,Model代表业务逻辑,View负责展示,Controller进行协调。用户请求被控制器...
07 Struts 2的基石——拦截器(Interceptor) 08 在Struts 2中实现IoC 09 在Struts 2中实现文件上传 10 在Struts 2中实现CRUD 11 Struts 2中的OGNL 12 trus 2的新表单标志的使用 13 Struts 2与AJAX Struts2中用...
Struts2.0是Java Web开发中的一个热门框架,它基于Model-View-Controller(MVC)设计模式,为开发者提供了构建动态Web应用程序的强大工具。API文档是理解任何框架核心功能的关键,对于Struts2.0也不例外。让我们深入...
### Struts2.0拦截器详解 #### 一、拦截器概述 在Struts2框架中,拦截器(interceptor)是一种非常重要的机制,用于在执行Action前后进行一系列预处理或后处理的操作。拦截器可以用来执行如参数拦截、类型转换、输入...
下面我们将深入探讨Struts2.0拦截器的完整知识体系。 1. **拦截器的概念** 拦截器类似于AOP(面向切面编程)中的通知,它是在Action执行前或执行后进行拦截,并可以修改Action的执行流程。在Struts2中,拦截器是...
2. **拦截器(Interceptor)**:拦截器是Struts2.0的一大特色,它可以实现通用的功能,如日志、权限检查等,无需在每个Action中重复编写。通过配置拦截器栈,可以灵活地控制请求的处理流程。 3. **OGNL(Object-...
4. **拦截器(Interceptor)**: 拦截器是Struts2的一大特色,它可以插入到Action调用链中,执行预处理或后处理任务,如日志记录、权限验证、性能统计等。通过组合不同的拦截器,可以实现复杂的业务逻辑。 5. **...
五、Struts2.0拦截器 拦截器是Struts2.0实现业务逻辑的重要手段,如ValidationInterceptor进行数据校验,ExceptionMappingInterceptor处理异常,LoginInterceptor实现登录控制等。拦截器可以自由组合,形成拦截器栈...
拦截器是Struts2.0框架中一个非常灵活且强大的特性,它可以在Action执行前后进行拦截,执行特定的逻辑,如权限检查、日志记录等。Struts2.0内置了多种拦截器,同时支持自定义拦截器,使得开发者可以根据应用需求定制...
Struts2.0是Java Web开发中一个非常重要的框架,它是Apache软件基金会的Jakarta项目下的一个开源产品,主要用于构建MVC(Model-View-Controller)模式的应用程序。本入门案例将带你逐步了解如何使用Struts2.0来创建...