简介:Struts 1.x 是一个流行的基于MVC设计模式的Java Web应用程序框架,Apache软件基金会的开源项目。本资源提供Struts 1.x的全中文API文档,涵盖了Action类、ActionForm、ActionMapping等核心概念。文档详细解释了框架内的各种类、接口、方法和常量,无需英文基础即可掌握Struts的核心功能。包含关键知识点如国际化、标签库、配置文件等,适合正在学习或使用Struts 1的开发者作为参考资料。
1. Struts 1.x 概述
Struts 1.x 是一个基于Java EE的MVC(Model-View-Controller)框架,它将Web应用的模型、视图和控制器三个核心组件相互分离,旨在简化与提高Web应用开发的效率与质量。Struts框架通过引入Action、ActionForm、ActionMapping、ActionForward等核心组件来实现其架构,让开发者能够将业务逻辑与展示逻辑清晰地分离开来。
Struts 1.x 最初由Craig McClanahan 创建,在Java社区中得到了广泛的采用,成为企业级应用开发中的主流解决方案之一。它通过配置文件(如struts-config.xml)来管理Web层的请求处理和页面导航,使得Web应用的结构和流程更加清晰,并有利于代码的重用和模块化开发。Struts 1.x虽然已经不是最前沿的技术,但其设计理念和一些概念至今仍对现代Web框架有所影响。
2. Action 类实现与作用
2.1 Action类的基本实现
2.1.1 Action类的继承与方法覆盖
Action类是Struts框架中处理HTTP请求的核心组件,它继承自 org.apache.struts.action.Action 类。所有的Action类都应该覆盖 execute 方法,该方法负责处理业务逻辑,并返回一个 ActionForward 对象,用于指示后续的操作方向。以下是一个简单的Action类实现示例:
public class LoginAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
// 假设这里是进行登录验证的业务逻辑
if (validateLogin(loginForm)) {
// 登录成功逻辑
return mapping.findForward("success");
} else {
// 登录失败逻辑
return mapping.findForward("error");
}
}
private boolean validateLogin(LoginForm loginForm) {
// 实现登录验证逻辑
return true;
}
}
2.1.2 Action类与业务逻辑的关联
Action类的主要职责是作为MVC模式中的控制器部分,连接前端的Form(通过ActionForm传递)和后端的业务逻辑(可能通过DAO访问数据库)。为了保持Action类的简洁,通常会把具体的业务逻辑处理委托给其他服务类,而Action类仅负责调用这些服务,并根据结果决定下一步的操作。
例如,可以创建一个服务类 LoginService :
public class LoginService {
public boolean login(LoginForm loginForm) {
// 实现登录验证逻辑,访问数据库
return true;
}
}
然后修改 LoginAction 类,使用 LoginService :
public class LoginAction extends Action {
private LoginService loginService = new LoginService();
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
if (loginService.login(loginForm)) {
// 登录成功逻辑
return mapping.findForward("success");
} else {
// 登录失败逻辑
return mapping.findForward("error");
}
}
}
在本示例中,我们引入了 LoginService 来处理具体的业务逻辑,并在 LoginAction 中通过调用 LoginService.login() 方法来完成验证。通过这种方式,我们可以保持Action类的职责清晰且易于管理。
2.2 Action类在请求处理中的角色
2.2.1 Action类的生命周期
Action类的生命周期是指从Action对象被创建,到其 execute 方法被调用,再到最终被Struts容器销毁的过程。Action类的实例并不是每次请求都创建的,Struts通过 ActionMapping 对象缓存Action实例,从而提高性能。通常,Action类被设计为无状态的,意味着它们不应持有任何请求间的状态信息。
2.2.2 Action类与请求分发机制
当一个HTTP请求到达Struts框架时,首先由 RequestProcessor 类处理,它将请求的数据封装到对应的 ActionForm 中,然后寻找与之关联的 Action 类。 Action 类的 execute 方法随后被调用,并根据其返回的 ActionForward 对象来决定是转发到另一个页面,还是重定向到另一个URL。
请求分发机制是通过配置文件 struts-config.xml 中的 action-mappings 部分来定义的,其中每个 action 标签对应一个 Action 类。例如:
<action path="/login"
type="com.example.LoginAction"
name="loginForm"
scope="request"
validate="true"
input="/login.jsp">
<forward name="success" path="/welcome.jsp"/>
<forward name="error" path="/login.jsp"/>
</action>
在上述配置中,当 /login 路径的请求到达时,Struts框架会实例化 LoginAction 类,并调用其 execute 方法。如果验证通过,则会跳转到 /welcome.jsp ,否则重新显示 /login.jsp 。
在这个过程中,Struts框架还负责管理ActionForm的生命周期,包括请求参数的收集、填充到Form对象中、Action执行后的Form验证,以及最终的Form销毁。这些细节使得开发者能够更加专注于业务逻辑的实现,而不需要过多关注底层的HTTP请求处理和响应细节。
3. ActionForm 封装与处理
3.1 ActionForm的作用与设计
3.1.1 ActionForm的封装原则
ActionForm在Struts 1.x框架中扮演着至关重要的角色,负责封装用户请求提交的数据,以及表单验证等任务。它的设计宗旨是提供一种方式,使得MVC模式中的模型层与视图层可以分离,同时避免控制器层的复杂度增加。
ActionForm的封装原则包含以下几个关键点:
- 数据封装: ActionForm需要提供与JSP表单字段相对应的属性,并且提供getter和setter方法以便于数据的存取。
- 数据校验: ActionForm应当实现Validation接口或继承自ValidatorForm类,以便于对提交的数据进行校验。
- 线程安全: 由于ActionForm在多用户环境下可能会被重复使用,它必须是线程安全的,这意味着不应该在ActionForm中存储请求特定的上下文信息。
- 对象持久化: 在某些情况下,ActionForm可能需要与数据库交互,实现对象的持久化操作。
3.1.2 ActionForm与数据校验
数据校验是ActionForm的一个核心功能。Struts提供了内置的校验框架,它允许开发者在ActionForm类中指定哪些字段需要进行哪些校验规则。开发者可以使用XML配置文件定义校验逻辑,也可以在ActionForm类中直接使用注解来完成。
校验逻辑的定义通常包含如下步骤:
1. 实现Validation接口或继承自ValidatorForm类。
2. 在ActionForm类中定义validate()方法,或在XML中配置校验规则。
3. 在validate()方法中使用ActionErrors对象收集校验错误信息。
4. 校验成功时,返回null或空的ActionErrors对象;校验失败时,返回包含错误信息的ActionErrors对象。
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
// 示例校验字段"username"
String username = getUserName();
if (username == null || username.length() == 0) {
errors.add("username", new ActionMessage("error.username.required"));
} else if (!username.matches("[a-zA-Z0-9]+")) {
errors.add("username", new ActionMessage("error.username.format"));
}
return errors;
}
在上述代码示例中,我们对用户名字段进行了非空和格式校验,并在发现错误时向ActionErrors中添加了错误信息。
3.2 ActionForm的实例化与应用
3.2.1 ActionForm的生命周期
ActionForm的生命周期从用户请求提交表单开始,直到Struts框架完成对请求的处理并返回响应结束。具体过程如下:
1. 实例化: 每次用户提交表单时,Struts框架会首先检查请求参数中是否包含与ActionForm类对应的参数。如果没有,框架会创建ActionForm实例并初始化其属性。如果已经存在实例,Struts会重用该实例。
2. 数据填充: 然后,Struts会调用该实例的setter方法,根据表单数据填充ActionForm的属性。
3. 校验与处理: ActionForm实例被传入Action类中进行处理,包括数据校验和业务逻辑的执行。
4. 数据回收: 请求处理完成后,Struts框架通常会将ActionForm实例存入请求范围(request scope)中,以便于在JSP页面中使用。处理完用户请求后,该实例会被Struts回收。
3.2.2 在Action类中使用ActionForm
Action类在处理用户请求时,往往需要依赖于ActionForm来提供数据。Action类的execute()方法接收一个ActionForm对象作为参数,这样Action就可以访问到ActionForm中的数据,并进行后续的处理。
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 强制类型转换
MyActionForm myForm = (MyActionForm) form;
String username = myForm.getUserName();
// 逻辑处理
// ...
return mapping.findForward("success");
}
在上述代码段中,execute()方法首先通过类型转换获取到正确的ActionForm实例,并从中提取出需要的数据进行处理。处理完成后,返回一个ActionForward对象,指示Struts框架接下来如何转发请求。
ActionForm的设计使视图层的数据可以很容易地传递到控制器层,为MVC模式的实施提供了便利。通过这种方式,Struts成功地将数据封装与数据校验集成到整个Web应用的请求处理流程中。
4. ActionMapping 映射规则
4.1 ActionMapping的基本概念
4.1.1 ActionMapping的配置参数
ActionMapping是Struts框架中用于定义请求映射和处理规则的组件。在Struts配置文件(struts-config.xml)中,ActionMapping对象负责指定如何将客户端的请求映射到后端的Action类,并决定如何处理这些请求。
ActionMapping的配置参数包括:
-
path:定义请求URL的路径部分,客户端请求时必须匹配此路径。 -
type:指定Action类的完全限定名,即类的包名加类名。 -
name:与ActionForm的name属性相对应,用于指定对应的ActionForm Bean。 -
scope:定义ActionForm Bean的作用域,默认为request。 -
validate:指定请求处理前是否进行表单验证。 -
input:指定输入表单的页面,如果验证失败则跳转到此页面。 -
unknown:当请求的action不匹配任何定义时,将调用的处理方法。 -
parameter:定义请求参数与ActionForm属性的映射关系。
4.1.2 映射规则的定义与示例
映射规则的定义涉及到将用户的请求动作与后端的Action类进行绑定。一个典型的ActionMapping配置示例如下:
<action-mappings>
<action path="/login" type="com.example.LoginAction" name="loginForm"
scope="request" validate="true" input="/login.jsp">
<forward name="success" path="/welcome.jsp"/>
<forward name="invalid" path="/login.jsp"/>
</action>
<!-- 其他映射规则 -->
</action-mappings>
在这个例子中,定义了一个处理登录请求的Action。路径为 /login 的请求将映射到 com.example.LoginAction 类。 loginForm 是与该Action类关联的ActionForm,而 validate="true" 表示在执行Action处理之前要进行表单验证。如果验证失败,将返回 input 属性指定的 /login.jsp 页面;如果登录成功,则会转发到 /welcome.jsp 页面。
4.2 ActionMapping与请求转发
4.2.1 ActionForward的配置与使用
ActionForward是Struts中的一个组件,用于控制在请求处理之后的转发流程。在ActionMapping配置中可以定义一个或多个ActionForward,以便在Action执行完毕后根据结果转发到不同的页面或资源。
ActionForward配置元素的属性包括:
-
name:ActionForward的唯一标识符。 -
path:转发的目标路径。
例如,在配置文件中定义两个转发目标:
<action path="/login" type="com.example.LoginAction" name="loginForm">
<forward name="success" path="/welcome.jsp"/>
<forward name="invalid" path="/login.jsp"/>
</action>
在 LoginAction 类中,执行完登录逻辑后,可以使用 ActionMapping 对象的 findForward 方法根据名称找到对应的 ActionForward 对象,并通过 forward 方法实现转发。
4.2.2 请求转发的流程分析
请求转发过程可以从客户端发起请求开始,然后经过Struts框架进行处理。请求首先被 RequestProcessor 类接收,该类会解析请求并根据配置文件中的ActionMapping找到对应的Action类。Action类执行后,返回一个 ActionForward 对象。该对象指示Struts框架将控制权和请求转发到下一个目标。
整个转发流程如下:
- 用户发起请求。
- 请求被Struts框架接收。
-
RequestProcessor根据请求路径找到对应的ActionMapping。 - ActionMapping创建Action实例并执行。
- Action实例处理请求逻辑并返回结果。
- 如果返回的是ActionForward对象,Struts框架根据
ActionForward中的信息进行页面转发或重定向。 - 用户端接收到新的页面响应。
通过这个流程,Struts框架将请求处理和页面转发解耦,使得Web应用的开发更加模块化和可维护。
graph LR
A[客户端发起请求] -->|路径匹配| B[RequestProcessor接收]
B --> C[解析ActionMapping]
C --> D[创建并执行Action]
D --> E[返回ActionForward]
E --> F[根据ActionForward转发]
F --> G[用户端接收响应]
在实际开发中,通过合理配置ActionMapping和ActionForward,可以使得Web应用的处理流程更加清晰,同时也便于维护和扩展。
5. Dispatcher 控制器功能
5.1 Dispatcher的工作原理
5.1.1 请求的接收与处理
Dispatcher是Struts 1.x框架的核心控制器,负责接收用户请求、处理请求,并将处理结果反馈给用户。在实际应用中,Dispatcher通过一个名为 struts-config.xml 的配置文件来识别和执行相应的业务逻辑。
当用户发起一个HTTP请求,Dispatcher首先会根据请求中的信息(如URL、请求方法等),在 struts-config.xml 中查找对应的 ActionMapping 。找到之后,它会根据 ActionMapping 提供的信息,创建相应的 Action 实例,并调用该实例的 execute() 方法来执行业务逻辑。
这一过程涉及以下几个关键步骤:
- 用户发起请求,Dispatcher接收到请求后,解析请求中的参数。
- Dispatcher根据请求中的信息匹配
ActionMapping。 - 如果找到匹配的
ActionMapping,Dispatcher将初始化ActionForm,将请求中的参数封装进ActionForm。 - 创建
Action实例,并将ActionForm对象传递给Action的execute()方法。 -
Action实例处理业务逻辑,并返回一个ActionForward对象给Dispatcher。 - Dispatcher根据
ActionForward对象指定的路径进行响应转发或页面跳转。
5.1.2 控制器的核心组件
Dispatcher作为整个Struts框架的协调者,其内部包含了多个核心组件,这些组件协同工作共同完成了请求的接收、处理和响应转发。
核心组件包括:
- ActionServlet :处理所有的HTTP请求,并负责初始化Dispatcher。
- RequestProcessor :负责解析请求,创建
ActionForm、Action实例,并调用它们的方法。 - ActionMapping :定义了请求与Action之间的映射关系。
- ActionForward :定义了请求处理完成后,控制权应该转向的URL。
- Action :具体的业务逻辑处理类。
- ActionForm :用于封装用户表单数据,并提供数据校验功能。
5.2 Dispatcher与Action类的协同工作
5.2.1 请求调度的步骤
为了详细理解Dispatcher如何与Action类协同工作,让我们深入探讨请求调度的步骤:
-
初始化阶段 :当Web服务器接收到用户的请求时,它会调用
ActionServlet。ActionServlet负责解析struts-config.xml配置文件,初始化所有的ActionMapping和ActionForm,以及其他组件。 -
请求解析阶段 :
RequestProcessor开始工作,它将解析请求参数,并查找对应的ActionMapping。如果找到,则继续下一步。 -
表单处理阶段 :如果
ActionMapping指定了一个ActionForm,RequestProcessor将负责创建ActionForm的实例,并从请求中读取参数,填充ActionForm。 -
Action实例化阶段 :
RequestProcessor接下来查找与ActionMapping关联的Action类,并创建其实例。如果有异常发生,请求可能被转发到错误处理页面。 -
执行Action阶段 :
RequestProcessor调用Action实例的execute()方法,并将ActionForm作为参数传递。Action执行业务逻辑,并返回一个ActionForward。 -
响应转发阶段 :最后,
RequestProcessor将根据ActionForward指定的路径转发请求。这可能是一个简单的转发,也可能是一个重定向,甚至是一个包含视图的JSP页面。
5.2.2 返回响应的处理机制
在请求处理完毕后,返回响应的处理机制是Struts框架流程中的重要一环。无论 Action 的 execute() 方法执行成功还是失败,返回的 ActionForward 都会告诉Dispatcher下一步应该做什么。
-
成功执行后 :如果
Action成功执行,ActionForward可能包含一个重定向URL或一个转发到特定JSP页面的路径。在重定向的情况下,用户浏览器的地址栏会发生变化,因为他们会被导向一个新的URL。而在转发的情况下,用户不会看到地址栏的变化,因为所有的动作都在服务器端完成,对用户来说是透明的。 -
执行失败后 :如果
Action处理失败,通常会返回一个ActionForward对象,该对象指定了一个错误处理页面。这可以是系统自定义的错误页面,或者也可以是使用Struts标签库中的<html:errors/>标签显示错误信息的JSP页面。
为了确保 ActionForward 正确处理,Struts提供了一个 ActionForward 类,它是一个包含了一系列属性(如name、path)的对象,用于指示Dispatcher接下来的操作。
public class ActionForward {
private String path;
private boolean redirect;
// ... 其他属性和方法 ...
}
在 Action 的 execute() 方法中,你可以通过以下方式返回一个 ActionForward 对象:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
// ... 业务逻辑代码 ...
ActionForward forward = new ActionForward();
forward.setPath("/success.jsp");
forward.setRedirect(true);
return forward;
}
在本章节中,我们详细探讨了Dispatcher控制器的工作原理以及它与Action类的协同工作过程。我们了解了请求的接收、处理以及最终响应的返回机制。接下来的章节我们将深入探讨Tiles扩展与页面布局的相关内容。
6. Tiles 扩展与页面布局
6.1 Tiles的布局扩展功能
6.1.1 Tiles定义与页面模板
Apache Struts的Tiles框架提供了一种简单而强大的方式来定义和使用页面模板。通过Tiles,开发者可以构建可重复使用的布局组件,从而减少页面之间的代码冗余,提高开发效率和可维护性。
Tiles组件通常定义在一个XML文件中,这些文件被称为definition files。每个definition file定义了一个页面布局模板,该模板可以被多个页面所共享。一个简单的Tiles definition可能包含如下的定义:
<definition name="baseLayout" template="/templates/layout.jsp">
<put-attribute name="header" value="/templates/header.jsp"/>
<put-attribute name="footer" value="/templates/footer.jsp"/>
</definition>
在这个例子中, baseLayout 是布局模板的名称,它引用了一个基础的JSP模板 layout.jsp ,并且指定了两个区域 header 和 footer ,分别对应的JSP文件在 header.jsp 和 footer.jsp 中定义。
6.1.2 动态组件与模板的整合
除了静态地定义组件之外,Tiles框架还允许开发者在模板中动态插入组件。通过在definition中定义属性,然后在页面中动态指定这些属性的值,可以实现组件的动态定制。
一个动态组件示例代码如下:
<definition name="userProfile" extends="baseLayout">
<put-attribute name="body" value="/users/profile.jsp"/>
</definition>
然后在页面中使用 userProfile 时可以这样定义:
<tile:insert attribute="header" />
<tile:insert attribute="body" />
<tile:insert attribute="footer" />
这样,页面就呈现了基础布局,其中 body 部分被 userProfile 的 profile.jsp 动态替换。这个动态特性使得页面布局更加灵活,能够满足复杂的应用需求。
6.2 Tiles在页面布局中的应用
6.2.1 布局的配置与管理
为了实现Tiles的布局功能,首先需要配置Tiles插件。在Struts的 struts.xml 配置文件中添加 Tiles 插件的配置信息:
<plug-in className="org.apache.struts2.tiles.StrutsTilesPlugin">
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
</plug-in>
这里的 definitions-config 指定了定义 Tiles 的XML文件的位置。在 /WEB-INF/tiles-defs.xml 中配置了所有Tile的定义,如前面提到的 baseLayout 和 userProfile 。
6.2.2 实现组件共享与定制布局
Tiles 能够使得多个页面共享相同的组件,例如导航菜单、页脚、侧边栏等。通过定义一个通用的布局模板,这些组件可以在多个页面中被重复使用,只需通过简单的配置即可实现。
为了定制布局,开发者可以在子页面中指定哪些部分需要被覆盖。比如在一个特定的页面中,你可能想要一个特别的页脚,你可以这样写:
<tile:insert page="userProfile" flush="true">
<tile:put-attribute name="header" value="/specialHeader.jsp"/>
<tile:put-attribute name="footer" value="/specialFooter.jsp"/>
</tile:insert>
在这个例子中,我们继承了 userProfile 的布局,并且只替换了 header 和 footer 两个部分,使用了特定的JSP文件来显示。
通过这种方式,可以实现既灵活又具有高度可维护性的页面布局,使网站的设计和开发都变得更加高效。
7. 国际化与本地化支持
在构建面向全球用户的Web应用时,国际化(I18n)与本地化(L10n)支持显得尤为重要。这不仅涉及到不同语言文本的翻译,还包括货币、日期、数字格式等本地习惯的适配。在本章中,我们将探讨Struts框架是如何通过特定的机制和实践来支持国际化和本地化的,以及如何应用到实际项目中。
7.1 国际化与本地化的基础概念
7.1.1 国际化的处理流程
国际化是设计软件时的过程,使其能够轻松地适应不同的区域和语言。在Struts中,国际化处理流程大致如下:
- 区域设置(Locale)识别 - 识别用户的语言偏好。
- 资源文件(message.properties) - 创建和维护针对不同区域的资源文件。
- 消息资源定位 - 根据当前区域设置,加载对应语言的资源文件。
- 文本消息获取 - 从资源文件中获取适合当前区域的消息文本。
7.1.2 本地化资源的配置与管理
资源文件通常放在 WebContent/WEB-INF/classes 目录下,命名规则为 message_语言代码_国家代码.properties ,例如 message_en_US.properties 和 message_zh_CN.properties 。资源文件中的键值对如下:
# message_en_US.properties
login.title = Login Page
login.username = Username
login.password = Password
通过这种方式,可以根据用户的需求,快速为不同的区域定制应用界面和用户体验。
7.2 实现国际化的Struts应用
7.2.1 多语言资源文件的创建与使用
创建多语言资源文件是实现国际化应用的基础。针对不同语言,创建对应的 .properties 文件,并确保每个文件都遵循相同的键名约定。例如,为中文创建一个 message_zh_CN.properties 文件:
# message_zh_CN.properties
login.title = 登录页面
login.username = 用户名
login.password = 密码
在Struts配置文件 struts.xml 中,需要配置本地化拦截器 i18n ,以支持资源文件的加载和区域设置:
<interceptors>
<interceptor name="i18n" class="org.apache.struts2.interceptor.I18nInterceptor"/>
</interceptors>
<action name="login" class="com.example.LoginAction">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="i18n"/>
</action>
7.2.2 动态语言切换与用户界面适配
为用户提供界面语言切换的功能,不仅提高了用户体验,还增强了应用的灵活性。在Struts中,我们可以通过实现一个Action来动态地改变用户的区域设置(Locale)。
public class LocaleAction extends ActionSupport {
private String language;
private String country;
// 省略getter和setter方法...
@Override
public String execute() throws Exception {
Locale locale = new Locale(language, country);
request.getSession().setAttribute("javax.servlet.jsp.jstl.fmt.locale.session", locale);
return SUCCESS;
}
}
在JSP页面上,可以通过设置标签库来使用当前区域设置的资源:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title><fmt:message key="login.title"/></title>
</head>
<body>
<form action="login" method="post">
<label for="username"><fmt:message key="login.username"/></label>
<input type="text" id="username" name="username"/>
<!-- 其他表单元素 -->
</form>
</body>
</html>
以上示例展示了如何通过配置和简单的代码实现,为Struts应用添加国际化支持。通过这种方式,开发者可以为来自不同地区和使用不同语言的用户提供定制化的体验。
简介:Struts 1.x 是一个流行的基于MVC设计模式的Java Web应用程序框架,Apache软件基金会的开源项目。本资源提供Struts 1.x的全中文API文档,涵盖了Action类、ActionForm、ActionMapping等核心概念。文档详细解释了框架内的各种类、接口、方法和常量,无需英文基础即可掌握Struts的核心功能。包含关键知识点如国际化、标签库、配置文件等,适合正在学习或使用Struts 1的开发者作为参考资料。
526

被折叠的 条评论
为什么被折叠?



