ActionServlet
是该 MVC 实现的 Command
部分,它是这一框架的核心。
ActionServlet
(Command)
创建并使用
Action
、
ActionForm
和
ActionForward
。如前所述,
struts-config.xml
文件配置该 Command。在创建 Web 项目时,您将扩展
Action
和
ActionForm
来解决特定的问题。文件
struts-config.xml
指示
ActionServlet
如何使用这些扩展的类。这种方法有几个优点:
- 应用程序的整个逻辑流程都存储在一个分层的文本文件中。这使得人们更容易查看和理解它,尤其是对于大型应用程序而言。
- 网页设计人员不必费力地阅读 Java 代码来理解应用程序的流程。
- Java 开发人员也不必在更改流程以后重新编译代码。
可以通过扩展
ActionServlet
来添加 Command 功能。
ActionForm
维护 Web
应用程序的会话状态。
ActionForm
是一个抽象类,必须为每个输入表单模型创建该类的子类。当我说
输入表单模型
时,是指
ActionForm
表示的是由 HTML
表单设置或更新的一般意义上的数据。例如,您可能有一个由 HTML
表单设置的
UserActionForm
。Struts
框架将执行以下操作:
- 检查
UserActionForm
是否存在;如果不存在,它将创建该类的一个实例。 - Struts 将使用 HttpServletRequest 中相应的域设置
UserActionForm
的状态。没有太多讨厌的request.getParameter()
调用。例如,Struts 框架将从请求流中提取fname
,并调用UserActionForm.setFname()
。 - Struts 框架在将
UserActionForm
传递给业务包装UserAction
之前将更新它的状态。 - 在将它传递给
Action
类之前,Struts 还会对UserActionForm
调用validation()
方法进行表单状态验证。 注: 这并不总是明智之举。别的网页或业务可能使用UserActionForm
,在这些地方,验证可能有所不同。在UserAction
类中进行状态验证可能更好。 - 可在会话级维护
UserActionForm
。
注:
-
struts-config.xml
文件控制 HTML 表单请求与ActionForm
之间的映射关系。 - 可将多个请求映射到
UserActionForm
。 -
UserActionForm
可跨多页进行映射,以执行诸如向导之类的操作。
Action
类是业务逻辑的一个包装。
Action
类的用途是将
HttpServletRequest
转换为业务逻辑。要使用
Action
,请创建它的子类并覆盖
process()
方法。
ActionServlet
(Command) 使用
perform()
方法将参数化的类传递给
ActionForm
。仍然没有太多讨厌的
request.getParameter()
调用。当事件进展到这一步时,输入表单数据(或 HTML
表单数据)已被从请求流中提取出来并转移到
ActionForm
类中。
注:扩展
Action
类时请注意简洁。
Action
类应该控制应用程序的流程,而不应该控制应用程序的逻辑。通过将业务逻辑放在单独的包或
EJB 中,我们就可以提供更大的灵活性和可重用性。
考虑
Action
类的另一种方式是 Adapter
设计模式。
Action
的用途是“将类的接口转换为客户机所需的另一个接口。Adapter
使类能够协同工作,如果没有
Adapter,则这些类会因为不兼容的接口而无法协同工作。”(摘自 Gof
所著的
Design Patterns - Elements of Reusable OO
Software
)。本例中的客户机是
ActionServlet
,它对我们的具体业务类接口一无所知。因此,Struts
提供了它能够理解的一个业务接口,即
Action
。通过扩展
Action
,我们使得我们的业务接口与 Struts
业务接口保持兼容。(一个有趣的发现是,
Action
是类而不是接口)。
Action
开始为一个接口,后来却变成了一个类。真是金无足赤。)
输入事件通常是在 HTTP 请求表单中发生的,servlet 容器将 HTTP
请求转换为
HttpServletRequest
。控制器查看输入事件并将请求分派给某个
Action
类。
struts-config.xml
确定
Controller 调用哪个
Action
类。
struts-config.xml
配置信息被转换为一组
ActionMapping
,而后者又被放入
ActionMappings
容器中。(您可能尚未注意到这一点,以
s
结尾的类就是容器)
ActionMapping
包含有关特定事件如何映射到特定
Action
的信息。
ActionServlet
(Command)
通过
perform()
方法将
ActionMapping
传递给
Action
类。这样就使
Action
可访问用于控制流程的信息。
ActionMappings
是
ActionMapping
对象的一个集合。