Struts 2 - 快速指南


基本MVC架构

模型视图控制器(通常称为MVC)是一种用于开发 Web 应用程序的模型视图控制器模式由以下三个部分组成 -

  • 模型- 负责维护数据的模式的最低级别。

  • 视图- 负责向用户显示全部或部分数据。

  • 控制器- 控制模型和视图之间交互的软件代码。

MVC 很受欢迎,因为它将应用程序逻辑与用户界面层隔离并支持关注点分离。在这里,控制器接收应用程序的所有请求,然后与模型一起准备视图所需的任何数据。然后,视图使用控制器准备的数据来生成最终的可呈现的响应。MVC 抽象可以用图形表示如下。

支柱MVC

该模型

该模型负责管理应用程序的数据。它响应来自视图的请求,还响应来自控制器的指令来更新自身。

风景

它意味着以特定格式呈现数据,由控制器决定呈现数据而触发。它们是基于脚本的模板系统,如 JSP、ASP、PHP,并且非常容易与 AJAX 技术集成。

控制器

控制器负责响应用户输入并在数据模型对象上执行交互。控制器接收输入,验证输入,然后执行修改数据模型状态的业务操作。

Struts2是一个基于MVC的框架。在接下来的章节中,让我们看看如何在 Struts2 中使用 MVC 方法。

Struts 2 - 概述

Struts2是一种流行且成熟的基于MVC设计模式的Web应用程序框架。Struts2不仅仅是Struts 1的新版本,而且是对Struts架构的完全重写。

Webwork框架最初以Struts框架为基础,其目标是提供一个基于Struts的增强和改进的框架,使开发人员更容易进行Web开发。

一段时间后,Webwork框架和Struts社区联手创建了著名的Struts2框架。

Struts 2 框架特性

以下是一些可能迫使您考虑 Struts2 的出色功能 -

  • POJO 表单和 POJO 操作- Struts2 取消了作为 Struts 框架不可或缺的一部分的操作表单。使用Struts2,您可以使用任何POJO来接收表单输入。同样,您现在可以将任何 POJO 视为 Action 类。

  • 标签支持- Struts2 改进了表单标签和新标签,使开发人员可以编写更少的代码。

  • AJAX 支持- Struts2 已经认识到 Web2.0 技术的接管,并通过创建 AJAX 标签将 AJAX 支持集成到产品中,该功能与标准 Struts2 标签非常相似。

  • 轻松集成- 现在,通过 Struts2 提供的各种集成,与 Spring、Tiles 和 SiteMesh 等其他框架的集成变得更加容易。

  • 模板支持- 支持使用模板生成视图。

  • 插件支持- Struts2 的核心Behave可以通过使用插件来增强和增强。Struts2 有许多可用的插件。

  • 分析- Struts2 提供集成的分析来调试和分析应用程序。除此之外,Struts 还借助内置调试工具提供集成调试。

  • 易于修改标签- Struts2 中的标签标记可以使用 Freemarker 模板进行调整。这不需要 JSP 或 java 知识。基本的 HTML、XML 和 CSS 知识足以修改标签。

  • 促进更少的配置- Struts2 借助使用各种设置的默认值来促进更少的配置。您不必进行任何配置,除非它偏离了 Struts2 设置的默认设置。

  • 查看技术- Struts2 对多种视图选项(JSP、Freemarker、Velocity 和 XSLT)有很好的支持

上面列出了Struts 2的十大功能,这些功能使其成为企业就绪框架。

Struts 2 的缺点

尽管 Struts 2 具有一系列出色的功能,但当前版本仍存在一些限制 - Struts 2 需要进一步改进。列出了一些要点 -

  • 更大的学习曲线- 要将 MVC 与 Struts 结合使用,您必须熟悉标准 JSP、Servlet API 和大型且复杂的框架。

  • 文档质量差- 与标准 servlet 和 JSP API 相比,Struts 的在线资源较少,许多初次用户发现 Apache 在线文档令人困惑且组织不良。

  • 不太透明- 对于 Struts 应用程序,与普通的基于 Java 的 Web 应用程序相比,幕后发生的事情要多得多,这使得理解该框架变得困难。

最后要注意的是,一个好的框架应该提供许多不同类型的应用程序可以使用它的通用Behave。

Struts 2是最好的 Web 框架之一,广泛用于富互联网应用程序 (RIA) 的开发。

Struts 2 - 环境设置

我们的第一个任务是运行一个最小的 Struts 2 应用程序。本章将指导您如何准备开发环境以开始使用 Struts 2。

我假设您的计算机上已经安装了 JDK (5+)、Tomcat 和 Eclipse。如果您没有安装这些组件,请按照快速通道上给定的步骤操作 -

第 1 步 - 设置 Java 开发工具包 (JDK)

您可以从 Oracle 的 Java 站点 - Java SE 下载下载最新版本的 SDK 。您将在下载的文件中找到安装 JDK 的说明,按照给定的说明进行安装和配置设置。最后,设置 PATH 和 JAVA_HOME 环境变量以引用包含 java 和 javac 的目录,通常分别为 java_install_dir/bin 和 java_install_dir。

如果您运行的是 Windows 并将 SDK 安装在 C:\jdk1.5.0_20 中,则应在 C:\autoexec.bat 文件中输入以下行。

set PATH = C:\jdk1.5.0_20\bin;%PATH%
set JAVA_HOME = C:\jdk1.5.0_20

或者,在 Windows NT/2000/XP 上 -

  • 您可以右键单击“我的电脑”,选择“属性”,然后选择“高级”,然后选择“环境变量”。然后,您将更新 PATH 值并按“确定”按钮。

  • 在 Unix(Solaris、Linux 等)上,如果 SDK 安装在 /usr/local/jdk1.5.0_20 中并且您使用 C shell,则需要将以下内容放入 .cshrc 文件中。

在 Unix(Solaris、Linux 等)上,如果 SDK 安装在 /usr/local/jdk1.5.0_20 中并且您使用 C shell,则需要将以下内容放入 .cshrc 文件中。

setenv PATH /usr/local/jdk1.5.0_20/bin:$PATH
setenv JAVA_HOME /usr/local/jdk1.5.0_20

或者,如果您使用 Borland JBuilder、Eclipse、IntelliJ IDEA 或 Sun ONE Studio 等集成开发环境 (IDE),请编译并运行一个简单的程序以确认 IDE 知道您安装 Java 的位置,否则按照给定的IDE文档。

第 2 步 - 设置 Apache Tomcat

您可以从https://tomcat.apache.org/下载最新版本的 Tomcat 。下载安装后,将二进制发行版解压到一个方便的位置。

例如,在 Windows 上的 C:\apache-tomcat-6.0.33 中,或在 Linux/Unix 上的 /usr/local/apachetomcat-6.0.33 中,并创建指向这些位置的 CATALINA_HOME 环境变量。

您可以通过在Windows机器上执行以下命令来启动Tomcat,或者您可以简单地双击startup.bat

%CATALINA_HOME%\bin\startup.bat
 
or
 
C:\apache-tomcat-6.0.33\bin\startup.bat

Tomcat 可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令来启动 -

$CATALINA_HOME/bin/startup.sh
 
or
 
/usr/local/apache-tomcat-6.0.33/bin/startup.sh

成功启动后,可以通过访问http://localhost:8080/ 来使用 Tomcat 附带的默认 Web 应用程序。如果一切正常,那么它应该显示以下结果 -

雄猫主页

有关配置和运行 Tomcat 的更多信息可以在此处包含的文档以及 Tomcat 网站上找到: https: //tomcat.apache.org/

可以通过在 Windows 机器上执行以下命令来停止 Tomcat -

%CATALINA_HOME%\bin\shutdown

or

C:\apache-tomcat-5.5.29\bin\shutdown

可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令来停止 Tomcat -

$CATALINA_HOME/bin/shutdown.sh

or

/usr/local/apache-tomcat-5.5.29/bin/shutdown.sh

第 3 步 - 设置 Eclipse (IDE)

本教程中的所有示例都是使用 Eclipse IDE 编写的。我建议您在计算机上安装最新版本的 Eclipse。

安装 Eclipse 从https://www.eclipse.org/downloads/下载最新的 Eclipse 二进制文件。下载安装后,将二进制发行版解压到一个方便的位置。

例如,在 Windows 上的 C:\eclipse 中,或在 Linux/Unix 上的 /usr/local/eclipse 中,最后适当地设置 PATH 变量。可以通过在 Windows 机器上执行以下命令来启动 Eclipse,也可以直接双击 eclipse.exe

%C:\eclipse\eclipse.exe

可以通过在 Unix(Solaris、Linux 等)机器上执行以下命令来启动 Eclipse -

$/usr/local/eclipse/eclipse

成功启动后,如果一切正常,应该显示以下结果 -

Eclipse 主页

第 4 步 - 设置 Struts2 库

现在,如果一切正常,那么您可以继续设置 Struts2 框架。以下是在您的计算机上下载并安装 Struts2 的简单步骤。

  • 选择是要在 Windows 还是 Unix 上安装 Struts2,然后继续下一步,下载适用于 Windows 的 .zip 文件和适用于 Unix 的 .tz 文件。

  • 从https://struts.apache.org/download.cgi下载最新版本的 Struts2 二进制文件。

  • 在编写本教程时,我下载了struts-2.0.14-all.zip,当您解压下载的文件时,它将为您提供 C:\struts-2.2.3 内的目录结构,如下所示。

斯特茨目录

第二步是在任何位置提取 zip 文件,我在Windows 7 计算机上的c:\文件夹中下载并提取了struts-2.2.3-all.zip,以便将所有 jar 文件放入C:\struts-2.2 .3\lib。确保正确设置 CLASSPATH 变量,否则在运行应用程序时会遇到问题。

Struts 2 - 架构

从较高的层面来看,Struts2 是一个拉式 MVC(或 MVC2)框架。Struts2 中的模型-视图控制器模式是通过以下五个核心组件实现的:

  • 行动
  • 拦截器
  • 价值堆栈/OGNL
  • 结果/结果类型
  • 查看技术

Struts 2与传统的 MVC 框架略有不同,其中操作扮演模型而不是控制器的角色,尽管存在一些重叠。

Struts 2 架构

上图描述了Struts2 高层架构的模型视图控制器。控制器是用Struts2调度 servlet 过滤器和拦截器实现的,该模型是用操作实现的,视图是结果类型和结果的组合。值堆栈和 OGNL 提供公共线程,链接并实现其他组件之间的集成。

除了上述组件之外,还会有很多与配置相关的信息。Web 应用程序的配置,以及操作、拦截器、结果等的配置。

这是 Struts 2 MVC 模式的架构概述。我们将在后续章节中更详细地介绍每个组件。

请求生命周期

根据上图,您可以了解Struts 2中用户请求生命周期的工作流程如下:

  • 用户向服务器发送请求,请求某些资源(即页面)。

  • 过滤器调度程序查看请求,然后确定适当的操作。

  • 配置的拦截器功能适用,例如验证、文件上传等。

  • 根据请求的操作执行选定的操作。

  • 同样,如果需要,配置的拦截器将用于进行任何后处理。

  • 最后,结果由视图准备并将结果返回给用户。

Struts 2 - Hello World 示例

正如您已经从 Struts 2 架构中了解到的那样,当您在 Struts 2 Web 应用程序中单击超链接或提交 HTML 表单时,控制器会收集输入,并将其发送到名为 Actions 的 Java 类。Action执行后,结果会选择一个资源来呈现响应。该资源通常是 JSP,但也可以是 PDF 文件、Excel 电子表格或 Java applet 窗口。

假设您已经构建了开发环境。现在,让我们继续构建我们的第一个Hello World Struts2项目。该项目的目标是构建一个 Web 应用程序,用于收集用户名并显示“Hello World”,后跟用户名。

我们必须为任何 Struts 2 项目创建以下四个组件 -

先生编号 组件及描述
1

行动

创建一个操作类,它将包含完整的业务逻辑并控制用户、模型和视图之间的交互。

2

拦截器

如果需要,创建拦截器,或使用现有拦截器。这是控制器的一部分。

3

看法

创建 JSP 与用户交互以获取输入并呈现最终消息。

4

配置文件

创建配置文件来耦合操作、视图和控制器。这些文件是struts.xml、web.xml、struts.properties。

我将使用 Eclipse IDE,以便在动态 Web 项目下创建所有必需的组件。现在让我们开始创建动态 Web 项目。

创建动态 Web 项目

启动 Eclipse,然后选择“文件”>“新建”>“动态 Web 项目”,输入项目名称为HelloWorldStruts2,并按照以下屏幕所示设置其余选项 -

你好世界斯特茨1

在接下来的屏幕中选择所有默认选项,最后选中“生成 Web.xml 部署描述符”选项。这将在 Eclipse 中为您创建一个动态 Web 项目。现在选择Windows > Show View > Project Explorer,您将看到项目窗口,如下所示 -

你好世界 Stuts2

现在将以下文件从 struts 2 lib 文件夹C:\struts-2.2.3\lib复制到我们项目的WEB-INF\lib文件夹。为此,您只需将以下所有文件拖放到 WEB-INF\lib 文件夹中即可。

  • 公共文件上传-xyzjar
  • 公共 io-xyzjar
  • commons-lang-xyjar
  • 公共日志记录 xyzjar
  • commons-logging-api-xyjar
  • freemarker-xyzjar
  • javassist-.xy.z.GA
  • 奥格尼-xyzjar
  • struts2-核心-xyzjar
  • xwork-core.xyzjar

创建动作类

Action类是Struts 2应用程序的关键,我们在Action类中实现大部分业务逻辑。因此,让我们在Java Resources > src下创建一个 java 文件 HelloWorldAction.java ,包名为com.tutorialspoint.struts2,其内容如下。

当用户单击 URL 时,Action 类响应用户操作。执行 Action 类的一个或多个方法并返回 String 结果。根据结果​​的值,呈现特定的 JSP 页面。

package com.tutorialspoint.struts2;

public class HelloWorldAction {
   private String name;

   public String execute() throws Exception {
      return "success";
   }
   
   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

这是一个非常简单的类,具有一个名为“name”的属性。我们为“name”属性提供了标准的 getter 和 setter 方法,以及返回字符串“success”的执行方法。

Struts 2框架将创建HelloWorldAction类的对象并调用执行的方法来响应用户的操作。您将业务逻辑放入此方法中,该方法最终返回 String 常量。换句话说,对于每个 URL,您必须实现一个操作类,并且您可以直接使用该类名称作为操作名称,也可以使用 struts.xml 文件映射到其他名称,如下所示。

创建视图

我们需要一个 JSP 来呈现最终消息,当发生预定义操作时,Struts 2 框架将调用此页面,并且此映射将在 struts.xml 文件中定义。因此,让我们在 Eclipse 项目的 WebContent 文件夹中创建以下 jsp 文件HelloWorld.jsp 。为此,请右键单击项目资源管理器中的 WebContent 文件夹,然后选择“新建”>“JSP 文件”

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      Hello World, <s:property value = "name"/>
   </body>
</html>

taglib 指令告诉 Servlet 容器该页面将使用Struts 2标记,并且这些标记前面将带有s

s:property 标记显示由HelloWorldAction 类的getName()方法返回的操作类属性“name> 的值。

创建主页

我们还需要在 WebContent 文件夹中创建index.jsp 。该文件将用作初始操作 URL,用户可以单击该 URL 来告诉 Struts 2 框架调用 HelloWorldAction 类的已定义方法并呈现 HelloWorld.jsp 视图。

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      <h1>Hello World From Struts2</h1>
      <form action = "hello">
         <label for = "name">Please enter your name</label><br/>
         <input type = "text" name = "name"/>
         <input type = "submit" value = "Say Hello"/>
      </form>
   </body>
</html>

上述视图文件中定义的hello操作将使用 struts.xml 文件映射到 HelloWorldAction 类及其执行方法当用户单击“提交”按钮时,Struts 2 框架将运行 HelloWorldAction 类中定义的执行方法,并根据该方法的返回值,选择适当的视图并将其呈现为响应。

配置文件

我们需要一个映射来将 URL、HelloWorldAction 类(模型)和 HelloWorld.jsp(视图)联系在一起。该映射告诉 Struts 2 框架哪个类将响应用户的操作(URL)、将执行该类的哪个方法以及根据该方法返回的 String 结果呈现哪个视图。

因此,让我们创建一个名为struts.xml的文件。由于 Struts 2 要求 struts.xml 存在于类文件夹中。因此,在 WebContent/WEB-INF/classes 文件夹下创建 struts.xml 文件。Eclipse 默认情况下不会创建“classes”文件夹,因此您需要自己创建。为此,请右键单击项目资源管理器中的 WEB-INF 文件夹,然后选择“新建”>“文件夹”。你的 struts.xml 应该看起来像 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true" />
   
   <package name = "helloworld" extends = "struts-default">
     <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction" 
         method = "execute">
         <result name = "success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

关于上述配置文件,需要理解几句话。在这里,我们将常量struts.devMode设置为true,因为我们在开发环境中工作,需要查看一些有用的日志消息。然后,我们定义一个名为helloworld的包。

当您想要将操作组合在一起时,创建包非常有用。在我们的示例中,我们将操作命名为“hello”,它对应于 URL /hello.action并由HelloWorldAction.class支持。HelloWorldAction.class的execute 方法是在调用URL /hello.action时运行方法。如果执行方法的结果返回“成功”,那么我们将用户带到HelloWorld.jsp

下一步是创建一个web.xml文件,它是对 Struts 2 的任何请求的入口点。Struts2 应用程序的入口点将是部署描述符 (web.xml) 中定义的过滤器。因此,我们将在 web.xml 中定义 org.apache.struts2.dispatcher.FilterDispatcher 类的条目。需要在WebContent下的WEB-INF文件夹下创建web.xml文件。当您创建项目时,Eclipse 已经为您创建了一个框架 web.xml 文件。因此,我们只需将其修改如下 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">
   
   <display-name>Struts 2</display-name>
   
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

我们已指定index.jsp 作为我们的欢迎文件。然后我们将 Struts2 过滤器配置为在所有 url 上运行(即与模式 /* 匹配的任何 url)

启用详细日志

您可以在使用 Struts 2 时通过在WEB-INF/classes文件夹下创建logging.properties文件来启用完整的日志记录功能。将以下两行保留在属性文件中 -

org.apache.catalina.core.ContainerBase.[Catalina].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].handlers = \
   java.util.logging.ConsoleHandler

默认的logging.properties指定一个ConsoleHandler用于将日志记录路由到stdout以及一个FileHandler。可以使用 SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST 或 ALL 设置处理程序的日志级别阈值。

就是这样。我们已准备好使用 Struts 2 框架运行 Hello World 应用程序。

执行申请的程序

右键单击项目名称,然后单击“导出”>“WAR 文件”以创建 War 文件。

然后将此 WAR 部署到 Tomcat 的 webapps 目录中。

最后,启动 Tomcat 服务器并尝试访问 URL http://localhost:8080/HelloWorldStruts2/index.jsp。这将为您提供以下屏幕 -

你好世界Struts4

输入值“Struts2”并提交页面。您应该看到下一页

你好世界Struts5

请注意,您可以将索引定义为 struts.xml 文件中的操作,在这种情况下,您可以将索引页面调用为http://localhost:8080/HelloWorldStruts2/index.action。检查下面如何将索引定义为操作 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "struts.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">

      <action name = "index">
         <result >/index.jsp</result>
      </action>

      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction" 
         method = "execute">
         <result name = "success">/HelloWorld.jsp</result>
      </action>

   </package>
</struts>

Struts 2 - 配置文件

本章将带您完成Struts 2应用程序所需的基本配置。在这里,我们将看到一些重要的配置文件(如web.xml、struts.xml、strutsconfig.xmlstruts.properties)的帮助下可以配置哪些内容

老实说,您只需使用web.xmlstruts.xml配置文件就可以开始工作(正如您在上一章中已经看到的那样,我们的示例使用这两个文件进行工作)。但是,为了您的了解,我们还将解释其他文件。

web.xml 文件

web.xml 配置文件是一个 J2EE 配置文件,它确定 servlet 容器如何处理 HTTP 请求的元素。严格来说它不是一个Struts2配置文件,但是它是一个需要配置Struts2才能工作的文件。

如前所述,此文件为任何 Web 应用程序提供了入口点。Struts2 应用程序的入口点将是部署描述符 (web.xml) 中定义的过滤器。因此,我们将在 web.xml 中定义FilterDispatcher类的条目 。需要在文件夹WebContent/WEB-INF下创建 web.xml 文件。

如果您在没有模板或生成它的工具(例如 Eclipse 或 Maven2)的帮助下开始,这是您需要配置的第一个配置文件。

以下是我们在上一个示例中使用的 web.xml 文件的内容。

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">
   
   <display-name>Struts 2</display-name>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

</web-app>

请注意,我们将 Struts 2 过滤器映射到/*,而不是/*.action,这意味着所有 url 都将由 struts 过滤器解析。当我们阅读“注释”章节时,我们将介绍这一点。

Struts.xml 文件

struts.xml文件包含您将在开发操作时修改配置信息。该文件可用于覆盖应用程序的默认设置,例如struts.devMode = false以及属性文件中定义的其他设置。该文件可以在文件夹WEB-INF/classes下创建。

让我们看一下我们在上一章解释的 Hello World 示例中创建的 struts.xml 文件。

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "struts.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">
     
      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction" 
         method = "execute">
         <result name = "success">/HelloWorld.jsp</result>
      </action>
      
      <-- more actions can be listed here -->

   </package>
   <-- more packages can be listed here -->

</struts>

首先要注意的是DOCTYPE。所有 struts 配置文件都需要具有正确的文档类型,如我们的小示例所示。<struts> 是根标签元素,在该元素下我们使用 <package> 标签声明不同的包。这里 <package> 允许配置的分离和模块化。当您有一个大型项目并且项目分为不同的模块时,这非常有用。

例如,如果您的项目具有三个域 - Business_application、customer_application 和 Staff_application,那么您可以创建三个包并将关联的操作存储在适当的包中。

包标签具有以下属性 -

先生编号 属性及描述
1

姓名(必填)

包的唯一标识符

2

延伸

这个包是从哪个包扩展而来的?默认情况下,我们使用 struts-default 作为基础包。

3

抽象的

如果标记为 true,则该包不可供最终用户使用。

4

名称空间

操作的唯一命名空间

常量标签以及 name 和 value 属性应该用于覆盖default.properties中定义的以下任何属性,就像我们刚刚设置struts.devMode属性一样。设置struts.devMode属性允许我们在日志文件中看到更多调试消息。

我们定义对应于我们想要访问的每个 URL 的操作标签,并定义一个带有execute() 方法的类,每当我们访问相应的 URL 时就会访问该方法。

结果决定执行操作后返回到浏览器的内容。从操作返回的字符串应该是结果的名称。结果按上面的操作进行配置,或者作为“全局”结果,可用于包中的每个操作。结果具有可选的名称类型属性。默认名称值为“成功”。

Struts.xml 文件会随着时间的推移而变大,因此通过包来分解它是模块化它的一种方法,但Struts提供了另一种模块化 struts.xml 文件的方法。您可以将该文件拆分为多个 xml 文件并按以下方式导入它们。

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <include file="my-struts1.xml"/>
   <include file="my-struts2.xml"/>
</struts>

我们没有涉及的另一个配置文件是 struts-default.xml。该文件包含 Struts 的标准配置设置,您不必为 99.99% 的项目触及这些设置。因此,我们不会详细介绍该文件。如果您有兴趣,请查看struts2-core-2.2.3.jar 文件中提供的default.properties文件。

Struts-config.xml 文件

struts-config.xml 配置文件是 Web 客户端中视图和模型组件之间的链接,但对于 99.99% 的项目,您不必触及这些设置。

配置文件基本上包含以下主要元素 -

先生编号 拦截器和描述
1

struts 配置

这是配置文件的根节点。

2

表单bean

您可以在此处将 ActionForm 子类映射到名称。您可以在 strutsconfig.xml 文件的其余部分甚至 JSP 页面上使用该名称作为 ActionForm 的别名。

3

全球前锋

此部分将 Web 应用程序上的页面映射到名称。您可以使用此名称来引用实际页面。这可以避免在网页上对 URL 进行硬编码。

4

动作映射

这是您声明表单处理程序的地方,它们也称为操作映射。

5

控制器

本节配置 Struts 内部结构,在实际情况中很少使用。

6

插入

本节告诉 Struts 在哪里可以找到属性文件,其中包含提示和错误消息

以下是示例 struts-config.xml 文件 -

<?xml version = "1.0" Encoding = "ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
   "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd">

<struts-config>

   <!-- ========== Form Bean Definitions ============ -->
   <form-beans>
      <form-bean name = "login" type = "test.struts.LoginForm" />
   </form-beans>

   <!-- ========== Global Forward Definitions ========= -->
   <global-forwards>
   </global-forwards>

   <!-- ========== Action Mapping Definitions ======== -->
   <action-mappings>
      <action
         path = "/login"
         type = "test.struts.LoginAction" >

         <forward name = "valid" path = "/jsp/MainMenu.jsp" />
         <forward name = "invalid" path = "/jsp/LoginView.jsp" />
      </action>
   </action-mappings>

   <!-- ========== Controller Definitions ======== -->
   <controller contentType = "text/html;charset = UTF-8"
      debug = "3" maxFileSize = "1.618M" locale = "true" nocache = "true"/>

</struts-config>

有关 struts-config.xml 文件的更多详细信息,请检查您的 struts 文档。

Struts.properties 文件

该配置文件提供了一种更改框架默认Behave的机制。实际上, struts.properties配置文件中包含的所有属性也可以使用init-param在web.xml中进行配置,也可以使用struts.xml配置文件中的常量标签进行配置。但是,如果您希望将这些内容分开并让 struts 更具体,那么您可以在文件夹WEB-INF/classes下创建此文件。

该文件中配置的值将覆盖 struts2-core-xyzjar 发行版中包含的default.properties中配置的默认值。您可以考虑使用struts.properties文件更改几个属性-

### When set to true, Struts will act much more friendly for developers
struts.devMode = true

### Enables reloading of internationalization files
struts.i18n.reload = true

### Enables reloading of XML configuration files
struts.configuration.xml.reload = true

### Sets the port that the server is run on
struts.url.http.port = 8080

这里任何以井号(#) 开头的行都将被假定为注释,并且将被Struts 2忽略。

Struts 2 - 动作

操作是 Struts2 框架的核心,就像任何 MVC(模型视图控制器)框架一样。每个 URL 都映射到一个特定的操作,该操作提供服务用户请求所需的处理逻辑。

但这一行动还具有另外两个重要作用。首先,操作在数据从请求到视图的传输中起着重要作用,无论是 JSP 还是其他类型的结果。其次,该操作必须协助框架确定哪个结果应该呈现将在请求响应中返回的视图。

创建动作

Struts2中操作的唯​​一要求是必须有一个无参方法返回 String 或 Result 对象,并且必须是 POJO。如果未指定无参数方法,则默认Behave是使用execute() 方法。

您可以选择扩展ActionSupport类,它实现了六个接口,包括Action接口。操作界面如下 -

public interface Action {
   public static final String SUCCESS = "success";
   public static final String NONE = "none";
   public static final String ERROR = "error";
   public static final String INPUT = "input";
   public static final String LOGIN = "login";
   public String execute() throws Exception;
}

让我们看一下 Hello World 示例中的操作方法 -

package com.tutorialspoint.struts2;

public class HelloWorldAction {
   private String name;

   public String execute() throws Exception {
      return "success";
   }
   
   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

为了说明操作方法控制视图的点,让我们对执行方法进行以下更改并扩展 ActionSupport 类,如下所示 -

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
   private String name;

   public String execute() throws Exception {
      if ("SECRET".equals(name)) {
         return SUCCESS;
      } else {
         return ERROR;  
      }
   }
   
   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

在此示例中,我们在执行方法中有一些逻辑来查看 name 属性。如果属性等于字符串“SECRET”,则返回SUCCESS作为结果,否则返回ERROR作为结果。因为我们扩展了ActionSupport,所以我们可以使用字符串常量SUCCESS和ERROR。现在,让我们修改 struts.xml 文件如下 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">
      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction"
         method = "execute">
         <result name = "success">/HelloWorld.jsp</result>
         <result name = "error">/AccessDenied.jsp</result>
      </action>
   </package>
</struts>

创建视图

让我们在 Eclipse 项目的 WebContent 文件夹中创建以下 jsp 文件HelloWorld.jsp。为此,请右键单击项目资源管理器中的 WebContent 文件夹,然后选择“新建”>“JSP 文件”。如果返回结果为 SUCCESS,则将调用此文件,SUCCESS 是 Action 接口中定义的字符串常量“success” -

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      Hello World, <s:property value = "name"/>
   </body>
</html>

以下是在操作结果为 ERROR(等于字符串常量“error”)时框架将调用的文件。以下是AccessDenied.jsp的内容

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>  
   <head>
      <title>Access Denied</title>
   </head>
   
   <body>
      You are not authorized to view this page.
   </body>
</html>

我们还需要在 WebContent 文件夹中创建index.jsp 。该文件将用作初始操作 URL,用户可以单击该 URL 来告诉 Struts 2 框架调用HelloWorldAction 类的执行方法并呈现 HelloWorld.jsp 视图。

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
   "http://www.w3.org/TR/html4/loose.dtd">

<html>  
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      <h1>Hello World From Struts2</h1>
      <form action = "hello">
         <label for = "name">Please enter your name</label><br/>
         <input type = "text" name = "name"/>
         <input type = "submit" value = "Say Hello"/>
      </form>
   </body>
</html>

就是这样,web.xml 文件不需要更改,所以让我们使用我们在示例章节中创建的相同 web.xml。现在,我们已准备好使用 Struts 2 框架运行Hello World应用程序。

执行应用程序

右键单击项目名称,然后单击“导出”>“WAR文件”以创建 War 文件。然后将此 WAR 部署到 Tomcat 的 webapps 目录中。最后,启动 Tomcat 服务器并尝试访问 URL http://localhost:8080/HelloWorldStruts2/index.jsp。这将为您提供以下屏幕 -

你好世界Struts4

让我们输入一个单词“秘密”,您应该看到以下页面 -

你好世界struts51

现在输入“秘密”以外的任何单词,您应该看到以下页面 -

你好世界struts6

创建多个动作

您将经常定义多个操作来处​​理不同的请求并向用户提供不同的 URL,因此您将定义不同的类,如下所示 -

package com.tutorialspoint.struts2;
import com.opensymphony.xwork2.ActionSupport;

class MyAction extends ActionSupport {
   public static String GOOD = SUCCESS;
   public static String BAD = ERROR;
}

public class HelloWorld extends ActionSupport {
   ...
   public String execute() {
      if ("SECRET".equals(name)) return MyAction.GOOD;
      return MyAction.BAD;
   }
   ...
}

public class SomeOtherClass extends ActionSupport {
   ...
   public String execute() {
      return MyAction.GOOD;
   }
   ...
}

您将在 struts.xml 文件中配置这些操作,如下所示 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true" />
   
   <package name = "helloworld" extends = "struts-default">
      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorld" 
         method = "execute">
         <result name = "success">/HelloWorld.jsp</result>
         <result name = "error">/AccessDenied.jsp</result>
      </action>
      
      <action name = "something" 
         class = "com.tutorialspoint.struts2.SomeOtherClass" 
         method = "execute">
         <result name = "success">/Something.jsp</result>
         <result name = "error">/AccessDenied.jsp</result>
      </action>
   </package>
</struts>

正如您在上面的假设示例中看到的,操作结果SUCCESSERROR是重复的。

为了解决这个问题,建议您创建一个包含结果的类。

Struts 2 - 拦截器

拦截器在概念上与 servlet 过滤器或 JDK 代理类相同。拦截器允许横切功能与操作和框架分开实现。您可以使用拦截器实现以下目的 -

  • 在调用操作之前提供预处理逻辑。

  • 在调用操作后提供后处理逻辑。

  • 捕获异常以便可以执行替代处理。

Struts2框架中提供的很多功能都是使用拦截器来实现的;

示例包括异常处理、文件上传、生命周期回调等。事实上,由于 Struts2 强调其大部分功能都在拦截器上,因此不太可能为每个操作分配 7 或 8 个拦截器。

Struts2框架拦截器

Struts 2 框架提供了一系列开箱即用的拦截器,这些拦截器已预先配置并可供使用。下面列出了一些重要的拦截器 -

先生编号 拦截器和描述
1

别名

允许参数在请求之间具有不同的名称别名。

2

复选框

通过为未选中的复选框添加 false 参数值来协助管理复选框。

3

转换错误

将字符串转换为参数类型的错误信息放入操作的字段错误中。

4

创建会话

如果 HTTP 会话尚不存在,则自动创建。

5

调试

为开发人员提供多种不同的调试屏幕。

6

执行并等待

当操作在后台执行时,将用户发送到中间等待页面。

7

例外

将从操作引发的异常映射到结果,从而允许通过重定向进行自动异常处理。

8

上传文件

方便轻松上传文件。

9

国际化

在用户会话期间跟踪选定的区域设置。

10

记录器

通过输出正在执行的操作的名称来提供简单的日志记录。

11

参数

设置操作的请求参数。

12

准备

这通常用于执行预处理工作,例如设置数据库连接。

13

轮廓

允许记录操作的简单分析信息。

14

范围

在会话或应用程序范围中存储和检索操作的状态。

15

Servlet配置

为操作提供对各种基于 servlet 的信息的访问。

16

计时器

以操作执行所需时间的形式提供简单的分析信息。

17 号

代币

检查有效令牌的操作以防止重复的表单提交。

18

验证

为操作提供验证支持

请查看 Struts 2 文档以获取有关上述拦截器的完整详细信息。但我将向您展示如何在 Struts 应用程序中一般使用拦截器。

如何使用拦截器?

让我们看看如何在我们的“Hello World”程序中使用现有的拦截器。我们将使用计时器拦截器,其目的是测量执行操作方法所需的时间。同时,我使用params拦截器,其目的是将请求参数发送到操作。您可以在不使用此拦截器的情况下尝试示例,您会发现未设置name属性,因为参数无法到达操作。

我们将保留在示例章节中创建的 HelloWorldAction.java、web.xml、HelloWorld.jsp 和 index.jsp 文件,但让我们修改struts.xml文件以添加拦截器,如下所示 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "struts.devMode" value = "true" />
   
   <package name = "helloworld" extends = "struts-default">
      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction"
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "timer" />
         <result name = "success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

右键单击项目名称,然后单击“导出”>“WAR 文件”以创建 War 文件。然后将此 WAR 部署到 Tomcat 的 webapps 目录中。最后,启动 Tomcat 服务器并尝试访问 URL http://localhost:8080/HelloWorldStruts2/index.jsp。这将产生以下屏幕 -

你好世界Struts 4

现在,在给定文本框中输入任意单词,然后单击“Say Hello”按钮来执行定义的操作。现在,如果您检查生成的日志,您将发现以下文本 -

INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM 
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

这里的底线是由于计时器拦截器而生成的,它告诉我们该操作总共花费了 109 毫秒来执行。

创建自定义拦截器

在应用程序中使用自定义拦截器是提供横切应用程序功能的一种优雅方式。创建自定义拦截器很容易;需要扩展的接口是以下拦截器接口 -

public interface Interceptor extends Serializable {
   void destroy();
   void init();
   String intercept(ActionInvocation invocation)
   throws Exception;
}

顾名思义,init() 方法提供了初始化拦截器的方法,destroy() 方法提供了拦截器清理的工具。与操作不同,拦截器在请求之间重用,并且需要线程安全,尤其是intercept()方法。

ActionIncation对象提供对运行时环境的访问它允许访问操作本身以及调用该操作的方法并确定该操作是否已被调用。

如果不需要初始化或清理代码,可以扩展AbstractInterceptor类。这提供了 init() 和 destroy() 方法的默认 nooperation 实现。

创建拦截器类

让我们在Java Resources > src文件夹中创建以下 MyInterceptor.java -

package com.tutorialspoint.struts2;

import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

   public String intercept(ActionInvocation invocation)throws Exception {

      /* let us do some pre-processing */
      String output = "Pre-Processing"; 
      System.out.println(output);

      /* let us call action or next interceptor */
      String result = invocation.invoke();

      /* let us do some post-processing */
      output = "Post-Processing"; 
      System.out.println(output);

      return result;
   }
}

正如您所注意到的,实际操作将使用拦截器通过invoking.invoke()调用来执行。因此,您可以根据您的要求进行一些预处理和后处理。

框架本身通过第一次调用 ActionIn Vocation 对象的 invoke() 来启动该过程。每次调用invoke()时,ActionInitation 都会查阅其状态并执行接下来出现的拦截器。当所有配置的拦截器都被调用时,invoke() 方法将导致操作本身被执行。

下图通过请求流显示了相同的概念 -

动作调用

创建动作类

让我们在Java Resources > src下创建一个 java 文件 HelloWorldAction.java ,包名为com.tutorialspoint.struts2,内容如下。

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
   private String name;

   public String execute() throws Exception {
      System.out.println("Inside action....");
      return "success";
   }  

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

这是我们在前面的示例中看到的同一类。我们为“name”属性提供了标准的 getter 和 setter 方法,以及返回字符串“success”的执行方法。

创建视图

让我们在 Eclipse 项目的 WebContent 文件夹中创建以下 jsp 文件HelloWorld.jsp

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      Hello World, <s:property value = "name"/>
   </body>
</html>

创建主页

我们还需要在 WebContent 文件夹中创建index.jsp 。该文件将用作初始操作 URL,用户可以单击该 URL 来告诉 Struts 2 框架调用 HelloWorldAction 类的已定义方法并呈现 HelloWorld.jsp 视图。

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      <h1>Hello World From Struts2</h1>
      <form action = "hello">
         <label for = "name">Please enter your name</label><br/>
         <input type = "text" name = "name"/>
         <input type = "submit" value = "Say Hello"/>
      </form>
   </body>
</html>

上述视图文件中定义的hello操作将使用 struts.xml 文件映射到 HelloWorldAction 类及其执行方法

配置文件

现在,我们需要注册我们的拦截器,然后调用它,就像我们在前面的示例中调用默认拦截器一样。要注册新定义的拦截器,请将 <interceptors>...</interceptors> 标记直接放置在struts.xml文件中的 <package> 标记下。对于默认拦截器,您可以跳过此步骤,就像我们在前面的示例中所做的那样。但在这里让我们注册并使用它,如下所示 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">

      <interceptors>
         <interceptor name = "myinterceptor"
            class = "com.tutorialspoint.struts2.MyInterceptor" />
      </interceptors>

      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction" 
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "myinterceptor" />
         <result name = "success">/HelloWorld.jsp</result>
      </action>

   </package>
</struts>

需要注意的是,您可以在<package>标记内注册多个拦截器,同时您可以在<action>标记内调用多个拦截器。您可以使用不同的操作调用相同的拦截器。

需要在 WebContent 下的 WEB-INF 文件夹下创建 web.xml 文件,如下所示 -

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">
   
   <display-name>Struts 2</display-name>
   
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

右键单击项目名称,然后单击“导出”>“WAR 文件”以创建 War 文件。然后将此 WAR 部署到 Tomcat 的 webapps 目录中。最后,启动 Tomcat 服务器并尝试访问 URL http://localhost:8080/HelloWorldStruts2/index.jsp。这将产生以下屏幕 -

你好世界Struts 4

现在,在给定文本框中输入任意单词,然后单击“Say Hello”按钮来执行定义的操作。现在,如果您检查生成的日志,您将在底部找到以下文本 -

Pre-Processing
Inside action....
Post-Processing

堆叠多个拦截器

正如您可以想象的那样,必须配置多个