Struts2 - 问题
Struts2 是基于 MVC 设计模式的流行且成熟的 Web 应用程序框架。 Struts2 不仅仅是 Struts 1 的下一个版本,而且是 Struts 架构的完全重写。
以下是一些可能迫使您考虑 Struts2 的出色功能 −
POJO 表单和 POJO 操作 − Struts2 已经废除了 Struts 框架不可或缺的一部分操作表单。使用 Struts2,您可以使用任何 POJO 来接收表单输入。同样,您现在可以将任何 POJO 视为操作类。
标签支持 − Struts2 改进了表单标签,新标签使开发人员可以编写更少的代码。
AJAX 支持 − Struts2 已认识到 Web2.0 技术的接管,并通过创建 AJAX 标签将 AJAX 支持集成到产品中,其功能与标准 Struts2 标签非常相似。
轻松集成 − 现在,由于 Struts2 提供多种集成功能,因此与其他框架(如 Spring、Tiles 和 SiteMesh)的集成变得更加容易。
模板支持 − 支持使用模板生成视图。
插件支持 − 通过使用插件可以增强和扩充核心 Struts2 行为。 Struts2 有许多可用的插件。
Struts2 中的模型-视图-控制器模式通过以下五个核心组件实现 −
操作
拦截器
值堆栈 / OGNL
结果 / 结果类型
视图技术
以下是 Struct2 应用程序中请求的生命周期 −
用户向服务器发送请求以获取某些资源(即页面)。
FilterDispatcher 查看请求,然后确定适当的操作。
配置的拦截器功能适用,例如验证、文件上传等。
执行选定的操作以执行请求的操作。
再次,如果需要,配置的拦截器将用于执行任何后期处理。
最后,视图准备结果并将结果返回给用户。
struts.xml 文件包含您将在开发操作时修改的配置信息。此文件可用于覆盖应用程序的默认设置,例如 struts.devMode = false 和属性文件中定义的其他设置。此文件可在文件夹 WEB-INF/classes 下创建。
constant 标签以及 name 和 value 属性将用于覆盖 default.properties 中定义的以下任何属性,就像我们刚刚设置 struts.devMode 属性一样。设置 struts.devMode 属性允许我们在日志文件中看到更多调试消息。
我们定义与要访问的每个 URL 相对应的 action 标签,并定义一个带有 execute() 方法的类,每当我们访问相应的 URL 时都会访问该方法。
结果决定执行操作后返回到浏览器的内容。从操作返回的字符串应该是结果的名称。结果按上述操作配置,或作为"全局"结果,可用于包中的每个操作。结果具有可选的名称和类型属性。默认名称值为"success"。
struts-config.xml 配置文件是 Web 客户端中视图和模型组件之间的链接。
在这里,您可以将 ActionForm 子类映射到名称。您可以在 struts-config.xml 文件的其余部分,甚至 JSP 页面上使用此名称作为 ActionForm 的别名。
此部分将您 webapp 上的页面映射到一个名称。您可以使用此名称来引用实际页面。这样可以避免在网页上硬编码 URL。
这是您声明表单处理程序的地方,它们也称为动作映射。
本节告诉 Struts 在哪里找到包含提示和错误消息的属性文件。
此配置文件提供了一种机制来更改框架。实际上,struts.properties 配置文件中包含的所有属性也可以使用 init-param 在 web.xml 中配置,也可以使用 struts.xml 配置文件中的 constant 标记进行配置。但是,如果您希望将所有内容分开并使其更具体,则可以在文件夹 WEB-INF/classes 下创建此文件。 此文件中配置的值将覆盖 struts2-core-x.y.z.jar 发行版中包含的 default.properties 中配置的默认值。
拦截器在概念上与 servlet 过滤器或 JDK 代理类相同。拦截器允许将横切功能与操作和框架分开实现。您可以使用拦截器 − 实现以下功能
在调用操作之前提供预处理逻辑。
在调用操作之后提供后处理逻辑。
捕获异常以便执行替代处理。
创建自定义拦截器很容易;需要扩展的接口是 Interceptor 接口。
实际操作将通过 invocation.invoke() 调用使用拦截器执行。因此,您可以根据需要进行一些预处理和后处理。
框架本身通过首次调用 ActionInvocation 对象的invoke() 来启动该过程。每次调用invoke() 时,ActionInvocation 都会查阅其状态并执行接下来的拦截器。当所有配置的拦截器都被调用后,invoke() 方法将导致操作本身被执行。
Action 类管理应用程序的状态,结果类型管理视图。
默认结果类型是 dispatcher,用于分派到 JSP 页面。
dispatcher 结果类型是默认类型,如果未指定其他结果类型,则使用该类型。它用于转发到服务器上的 servlet、JSP、HTML 页面等。它使用 RequestDispatcher.forward() 方法。
重定向结果类型调用标准 response.sendRedirect() 方法,导致浏览器向给定位置创建新请求。 我们可以在 <result...> 元素的主体中提供位置,也可以将其作为 <param name = "location">元素。
值堆栈是一组多个对象,它们按提供的顺序保存以下对象 −
临时对象 − 在执行页面期间会创建各种临时对象。例如,在 JSP 标记中循环的集合的当前迭代值。
模型对象 − 如果您在 struts 应用程序中使用模型对象,则当前模型对象将放置在值堆栈上的操作之前。
操作对象 − 这将是正在执行的当前操作对象。
命名对象 −这些对象包括 #application、#session、#request、#attr 和 #parameters,并引用相应的 servlet 范围。
对象图导航语言 (OGNL) 是一种强大的表达语言,用于引用和操作 ValueStack 上的数据。OGNL 还有助于数据传输和类型转换。
ActionContext 映射由以下 −
application − 应用程序范围变量。
session − 会话范围变量。
root / 值堆栈 − 所有操作变量都存储在此处。
request − 请求范围变量。
parameters − 请求参数。
atributes −存储在页面、请求、会话和应用程序范围中的属性。
Struts 中的文件上传可以通过预定义的拦截器 FileUpload 拦截器进行,该拦截器可通过 org.apache.struts2.interceptor.FileUploadInterceptor 类获得,并作为 defaultStack 的一部分包含在内。
以下是控制文件上传过程的 Struts2 配置属性 −
struts.multipart.maxSize − 接受文件上传的最大文件大小(以字节为单位)。默认值为 250M。
struts.multipart.parser − 用于上传多部分表单的库。默认情况下为 jakarta。
struts.multipart.saveDir − 存储临时文件的位置。默认情况下是javax.servlet.context.tempdir。
fileUplaod拦截器使用几个默认的错误消息键 −
struts.messages.error.uploading − 文件无法上传时发生的一般错误。
struts.messages.error.file.too.large −当上传的文件大于 maximumSize 所指定的值时发生。
struts.messages.error.content.type.not.allowed −当上传的文件与指定的预期内容类型不匹配时发生。
您可以在 WebContent/WEB-INF/classes/messages.properties 资源文件中覆盖这些消息的文本。
在 Struts 的核心中,我们有一个验证框架,它帮助应用程序在执行操作方法之前运行规则以执行验证。 Action 类应扩展 ActionSupport 类,以便执行验证方法。
当用户按下提交按钮时,Struts 2 将自动执行验证方法,如果方法中列出的任何 if 语句为真,Struts 2 将调用其 addFieldError 方法。如果添加了任何错误,则 Struts 2 将不会继续调用执行方法。相反,Struts 2 框架将返回输入作为调用操作的结果。
因此,当验证失败且 Struts 2 返回输入时,Struts 2 框架将重新显示视图文件。由于我们使用了 Struts 2 表单标签,Struts 2 会自动将错误消息添加到表单字段的正上方。
这些错误消息是我们在 addFieldError 方法调用中指定的。addFieldError 方法有两个参数。第一个是错误适用的表单字段名称,第二个是要显示在该表单字段上方的错误消息。
进行验证的第二种方法是将 xml 文件放在操作类旁边。 Struts2 基于 XML 的验证提供了更多验证选项,如电子邮件验证、整数范围验证、表单验证字段、表达式验证、正则表达式验证、必需验证、必需字符串验证、字符串长度验证等。
xml 文件需要命名为 '[action-class]'-validation.xml。
以下是 Struts2 中可用的各种字段级和非字段级验证类型的列表 −
日期验证器
双重验证器
电子邮件验证器
表达式验证器
整数验证器
正则表达式验证器
必需验证器
必需字符串验证器
字符串长度验证器
url 验证器
国际化 (i18n) 是规划和实施产品和服务的过程,以便它们可以轻松适应特定的本地语言和文化,这一过程称为本地化。国际化过程有时称为翻译或本地化启用。
Struts2 通过以下位置的资源包、拦截器和标记库提供本地化,即国际化 (i18n) 支持 −
UI 标记。
消息和错误。
在操作类中。
资源文件最简单的命名格式是 −
bundlename_language_country.properties
此处的 bundlename 可以是 ActionClass、Interface、SuperClass、Model、Package、Global 资源属性。下一部分 language_country 表示国家/地区语言环境,例如西班牙语(西班牙)语言环境由 es_ES 表示,英语(美国)语言环境由 en_US 表示等。此处您可以跳过可选的国家/地区部分。
当您通过其键引用消息元素时,Struts 框架将按以下顺序搜索相应的消息包 −
ActionClass.properties
Interface.properties
SuperClass.properties
model.properties
package.properties
struts.properties
global.properties
StrutsTypeConverter 类通过重写两个方法 convertFromString() 和 convertToString() 告诉 Struts 如何将 Environment 转换为字符串,反之亦然。
Struts 2 附带三个内置主题 −
简单主题 − 一个没有"花哨"的极简主题。例如,textfield 标签呈现 HTML <input/> 标签,没有标签、验证、错误报告或任何其他格式或功能。
xhtml 主题 − 这是 Struts 2 使用的默认主题,提供简单主题提供的所有基本功能,并添加了一些功能,如 HTML 的标准两列表格布局、每个 HTML 的标签、验证和错误报告等。
css_xhtml 主题 −此主题提供了简单主题提供的所有基本功能,并添加了几个功能,例如基于 CSS 的标准两列布局,使用 <div> 作为 HTML Struts 标记,为每个 HTML Struts 标记添加标签,并根据 CSS 样式表进行放置。
Struts 通过使用"异常"拦截器使异常处理变得简单。"异常"拦截器包含在默认堆栈中,因此您无需执行任何额外操作即可对其进行配置。它开箱即用,可供您使用。
@Results 注解是结果的集合。在 @Results 注解下,我们可以有多个 @Result 注解。
@Results({ @Result(name = "success", value = "/success.jsp"), @Result(name = "error", value = "/error.jsp") }) public class Employee extends ActionSupport{ ... }
@result 注解的名称与执行方法的结果相对应。它们还包含应根据 execute() 的返回值提供哪个视图的位置。
@Result(name = "success", value = "/success.jsp") public class Employee extends ActionSupport{ ... }
这用于修饰 execute() 方法。Action 方法还接受一个值,该值是调用操作的 URL。
public class Employee extends ActionSupport{ private String name; private int age; @Action(value = "/empinfo") public String execute() { return SUCCESS; } }
@After 注解标记需要在主操作方法执行并执行结果后调用的操作方法。返回值将被忽略。
public class Employee extends ActionSupport{ @After public void isValid() throws ValidationException { // 验证模型对象,如果失败则抛出异常 } public String execute() { // 执行安全操作 return SUCCESS; } }
@Before 注解标记需要在主操作方法和结果执行之前调用的操作方法。返回值被忽略。
public class Employee extends ActionSupport{ @Before public void isAuthorized() throws AuthenticationException { // 授权请求,如果失败则抛出异常 } public String execute() { // 执行安全行动 return SUCCESS; } }
@BeforeResult 注解标记需要在结果之前执行的操作方法。返回值被忽略。
public class Employee extends ActionSupport{ @BeforeResult public void isValid() throws ValidationException { // 验证模型对象,如果失败则抛出异常 } public String execute() { // 执行动作 return SUCCESS; } }
此验证注解检查字段是否存在任何转换错误,如果存在则应用它们。
public class Employee extends ActionSupport{ @ConversionErrorFieldValidator(message = "Default message", key = "i18n.key", shortCircuit = true) public String getName() { return name; } }
此验证注解检查日期字段的值是否在指定范围内。
public class Employee extends ActionSupport{ @DateRangeFieldValidator(message = "Default message", key = "i18n.key", shortCircuit = true, min = "2005/01/01", max = "2005/12/31") public String getDOB() { return dob; } }
此验证注解检查双精度字段的值是否在指定范围内。如果未设置最小值和最大值,则不会执行任何操作。
public class Employee extends ActionSupport{ @DoubleRangeFieldValidator(message = "Default message", key = "i18n.key", shortCircuit = true, minInclusive = "0.123", maxInclusive = "99.987") public String getIncome() { return income; } }
此验证注解检查字段是否包含非空字符串,是否为有效的电子邮件地址。
public class Employee extends ActionSupport{ @EmailValidator(message = "Default message", key = "i18n.key", shortCircuit = true) public String getEmail() { return email; } }
此非字段级验证器验证提供的正则表达式。
@ExpressionValidator(message = "Default message", key = "i18n.key", shortCircuit = true, expression = "an OGNL expression" )
此验证注解检查数字字段的值是否在指定范围内。如果未设置最小值和最大值,则不会执行任何操作。
public class Employee extends ActionSupport{ @IntRangeFieldValidator(message = "Default message", key = "i18n.key", shortCircuit = true, min = "0", max = "42") public String getAge() { return age; } }
此注解使用正则表达式验证字符串字段。
@RegexFieldValidator( key = "regex.field", expression = "yourregexp")
此验证注解检查字段是否为非空。注解必须在方法级别应用。
public class Employee extends ActionSupport{ @RequiredFieldValidator(message = "Default message", key = "i18n.key", shortCircuit = true) public String getAge() { return age; } }
此验证注解检查字符串字段是否不为空(即非空且长度 > 0)。
public class Employee extends ActionSupport{ @RequiredStringValidator(message = "Default message", key = "i18n.key", shortCircuit = true, trim = true) public String getName() { return name; } }
此验证器检查字符串字段的长度是否正确。它假定该字段是字符串。如果未设置 minLength 和 maxLength,则不会执行任何操作。
public class Employee extends ActionSupport{ @StringLengthFieldValidator(message = "Default message", key = "i18n.key", shortCircuit = true, trim = true, minLength = "5", maxLength = "12") public String getName() { return name; } }
此验证器检查字段是否为有效 URL。
public class Employee extends ActionSupport{ @UrlValidator(message = "Default message", key = "i18n.key", shortCircuit = true) public String getURL() { return url; } }
如果要使用多个相同类型的注解,则这些注解必须嵌套在 @Validations() 注解中。
public class Employee extends ActionSupport{ @Validations( requiredFields = {@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "customfield", message = "You must enter a value for field.")}, requiredStrings = {@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "stringisrequired", message = "You must enter a value for string.")} ) public String getName() { return name; } }
此注解可用于自定义验证器。使用 ValidationParameter 注解提供其他参数。
@CustomValidator(type ="customValidatorName", fieldName = "myField")
这是类型级别类型转换的标记注解。转换注解必须在类型级别应用。
@Conversion() public class ConversionAction implements Action { }
此注解设置 CreateIfNull 进行类型转换。CreateIfNull 注解必须在字段或方法级别应用。
@CreateIfNull( value = true ) private List<User> users;
此注解设置 Element 进行类型转换。Element 注解必须在字段或方法级别应用。
@Element( value = com.acme.User ) private List<User> userList;
此注解设置类型转换的 Key。Key 注解必须在字段或方法级别应用。
@Key( value = java.lang.Long.class ) private Map<Long, User> userMap;
此注解设置类型转换的 KeyProperty。KeyProperty 注解必须在字段或方法级别应用。
@KeyProperty( value = "userName" ) protected List<User> users = null;
此注解用于类和应用程序范围的转换规则。TypeConversion 注解可应用于属性和方法级别。
@TypeConversion(rule = ConversionRule.COLLECTION, converter = "java.util.String") public void setUsers( List users ) { this.users = users; }