杰瑞科技汇

Struts教程,如何快速入门Java开发?

Java Struts 教程:从入门到实践

目录

  1. 什么是 Struts 2?
  2. 为什么学习 Struts 2?(虽然过时,但仍有价值)
  3. 核心概念:MVC 设计模式
  4. 环境搭建
    • 安装 JDK
    • 安装 IDE (IntelliJ IDEA / Eclipse)
    • 安装 Maven
  5. 创建第一个 Struts 2 应用程序:Hello World
    • 第 1 步:创建 Maven Web 项目
    • 第 2 步:添加 Struts 2 依赖
    • 第 3 步:配置 web.xml
    • 第 4 步:创建 Action 类
    • 第 5 步:创建视图(JSP)
    • 第 6 步:配置 struts.xml
    • 第 7 步:部署和运行
  6. Struts 2 核心组件详解
    • Action:业务逻辑控制器
    • Interceptor (拦截器):AOP 思想的体现
    • Result (结果):视图的映射
    • OGNL (Object-Graph Navigation Language):表达式语言
    • ValueStack (值栈):数据存储的核心
  7. 常用标签库
    • 数据标签 (s:property, s:iterator)
    • UI 标签 (s:form, s:textfield, s:submit)
    • 控制标签 (s:if, s:else, s:iterator)
  8. 数据接收与验证
    • 属性驱动接收
    • 模型驱动接收
    • 手动验证
    • 基于验证框架的验证 (validation.xml)
  9. 文件上传
  10. 总结与展望

什么是 Struts 2?

Struts 2 是一个用于开发 Java EE Web 应用程序的开源框架,它遵循经典的 MVC (Model-View-Controller) 设计模式,旨在帮助开发者创建可维护、可扩展和结构清晰的 Web 应用。

Struts教程,如何快速入门Java开发?-图1
(图片来源网络,侵删)

重要提示:Struts 1 和 Struts 2 是两个完全不同的框架,Struts 2 虽然名字上延续了 Struts 1,但其核心代码源自另一个名为 WebWork 的框架,Struts 2 的架构、API 和使用方式与 Struts 1 有很大不同,更加现代化和灵活。

为什么学习 Struts 2?(虽然过时,但仍有价值)

Struts 2 在 2010 年左右非常流行,是 Java Web 开发领域的主流框架之一,随着 Spring MVC 和后来 Spring Boot 的崛起,Struts 2 的使用率已大幅下降,并且历史上曝出过严重的安全漏洞(如 CVE-2025-5638)。

为什么我们还要学习它?

  • 学习历史:了解 Struts 2 有助于理解 Java Web 开发框架的演进史,很多老项目仍在使用 Struts 2,维护这些项目需要相关知识。
  • 理解 MVC:Struts 2 对 MVC 模式的实现非常经典和清晰,是学习 MVC 设计模式的一个绝佳范例。
  • 概念相通:Struts 2 中的许多核心概念(如拦截器、值栈、OGNL)在其他现代框架(如 Spring MVC)中也有类似的实现,学习 Struts 2 可以帮助你更好地理解这些通用思想。

Struts 2 已不是现代 Web 开发的首选,但它是一个优秀的学习工具和重要的技术遗产。

Struts教程,如何快速入门Java开发?-图2
(图片来源网络,侵删)

核心概念:MVC 设计模式

Struts 2 完美地实现了 MVC 模式,将应用分为三个部分:

  • Model (模型)

    • 职责:代表应用程序的数据和业务逻辑。
    • 实现:通常是普通的 Java 对象(POJO),包含属性和对应的 getter/setter 方法,它不依赖于任何 Struts 2 的 API。
  • View (视图)

    • 职责:负责显示数据,为用户提供交互界面。
    • 实现:通常是 JSP 页面,但也可以是 Velocity、Freemarker 等模板技术,Struts 2 提供了强大的标签库来简化视图层的开发。
  • Controller (控制器)

    Struts教程,如何快速入门Java开发?-图3
    (图片来源网络,侵删)
    • 职责:接收用户请求,调用 Model 处理业务逻辑,然后选择合适的 View 进行响应。
    • 实现:在 Struts 2 中,控制器由框架本身开发者编写的 Action 类共同构成。
      • 用户请求首先到达 Struts 2 的核心过滤器 FilterDispatcher (或 StrutsPrepareAndExecuteFilter)。
      • 过滤器根据配置 (struts.xml) 找到对应的 Action 类。
      • Action 类执行业务逻辑,并返回一个字符串(称为 "result code")。
      • 框架根据这个 result code 在 struts.xml 中找到对应的视图(JSP)并渲染。

环境搭建

在开始之前,确保你的电脑上安装了以下软件:

  1. JDK:版本 8 或更高。
  2. IDE:IntelliJ IDEA (推荐) 或 Eclipse。
  3. Maven:用于项目管理和依赖管理。

创建第一个 Struts 2 应用程序:Hello World

我们将创建一个简单的应用,用户在输入框中输入姓名,点击提交后,页面会显示 "Hello, [姓名]!"。

第 1 步:创建 Maven Web 项目

在 IDEA 中,选择 File -> New -> Project,然后选择 Maven,并勾选 Create from archetype,选择 maven-archetype-webapp,填写项目信息,完成创建。

第 2 步:添加 Struts 2 依赖

打开 pom.xml 文件,在 <dependencies> 标签内添加 Struts 2 的核心依赖。

<dependencies>
    <!-- Struts 2 核心依赖 -->
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <version>2.5.33</version> <!-- 使用一个较新的稳定版本 -->
    </dependency>
    <!-- 为了支持 JSP 视图,需要包含这个依赖 -->
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-junit-plugin</artifactId>
        <version>2.5.33</version>
    </dependency>
    <!-- 注意:上面的 JUnit 插件是测试用的,真正支持 JSP 的是 struts2-core 自带的,
         但有时会显式加入 struts2-convention-plugin 来支持约定优于配置。
         这里我们先使用最核心的。 -->
    <!-- Servlet API 依赖,因为 Web 项目需要 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- JSP API 依赖 -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

第 3 步:配置 web.xml

src/main/webapp/WEB-INF/web.xml 文件中,配置 Struts 2 的核心过滤器,这个过滤器是所有请求的入口。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 配置 Struts 2 的核心过滤器 -->
    <filter>
        <filter-name>struts2</filter-name>
        <!-- 注意:在较新的 Struts 2 版本中,类名是 StrutsPrepareAndExecuteFilter -->
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <!-- 拦截所有请求 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

第 4 步:创建 Action 类

src/main/java 目录下创建你的包结构,com.example.action,然后创建一个 Action 类。

HelloWorldAction.java:

package com.example.action;
public class HelloWorldAction {
    // 1. 定义一个属性,用于接收表单数据
    private String name;
    // 2. 必须提供 getter 和 setter
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    // 3. 执行业务逻辑的方法,必须是 public 且无参数
    // Struts 2 会默认调用这个方法
    public String execute() {
        // 这里可以添加业务逻辑,比如调用 Service 层
        System.out.println("HelloWorldAction.execute() is called. Name: " + name);
        return "success"; // 返回一个逻辑视图名称
    }
}

第 5 步:创建视图(JSP)

src/main/webapp 目录下创建 JSP 文件。

index.jsp (输入页面):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>Struts 2 Hello World</title>
</head>
<body>
    <h2>请输入您的名字</h2>
    <!-- 使用 Struts 2 的 form 标签 -->
    <s:form action="hello">
        <s:textfield name="name" label="姓名"/>
        <s:submit value="提交"/>
    </s:form>
</body>
</html>

hello.jsp (成功页面):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>欢迎页面</title>
</head>
<body>
    <h2>欢迎!</h2>
    <!-- 使用 s:property 标签从值栈中获取 name 属性的值 -->
    <p>Hello, <s:property value="name"/>!</p>
</body>
</html>

注意:JSP 页面顶部必须引入 <%@ taglib prefix="s" uri="/struts-tags" %> 才能使用 Struts 2 的标签。

第 6 步:配置 struts.xml

这是 Struts 2 的核心配置文件,它负责将 URL 映射到 Action,以及将 Action 的返回值映射到物理视图。

  1. src/main/resources 目录下创建 struts.xml 文件。
  2. Struts 2 的 DTD 比较严格,建议直接复制以下模板。

struts.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <!-- 开发模式下,可以打印更详细的日志,但生产环境要关闭 -->
    <constant name="struts.devMode" value="true"/>
    <!-- package: 用于组织 Action,name 是包名,extends="struts-default" 表示继承 Struts 2 的默认配置 -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- action: 定义一个 Action
             name: 对应 URL 中的 action 名,<s:form action="hello"> 中的 hello
             class: 指定处理请求的 Action 类的全限定名
             method: 指定调用 Action 类中的哪个方法,默认是 execute
        -->
        <action name="hello" class="com.example.action.HelloWorldAction" method="execute">
            <!-- result: 定义处理结果
                 name: 对应 Action 方法返回的字符串,execute() 返回的 "success"
                 type: 结果类型,默认是 "dispatcher",用于转发到 JSP
            -->
            <result name="success">/hello.jsp</result>
            <!-- 可以定义其他结果,例如输入验证失败时 -->
            <result name="input">/index.jsp</result>
        </action>
    </package>
</struts>

第 7 步:部署和运行

  1. 将项目部署到 Tomcat 或其他 Servlet 容器中。
  2. 启动服务器。
  3. 在浏览器中访问 http://localhost:8080/你的项目名/
  4. 在输入框中输入你的名字,点击提交,你应该会看到跳转到 hello.jsp 并显示欢迎信息。

Struts 2 核心组件详解

Action

Action 是 MVC 中的 C(控制器),它是一个简单的 POJO,不需要继承任何父类或实现接口(虽然可以实现 Action 接口来获得一些预定义的返回值常量),它的核心方法是 execute(),但你可以通过配置 method 属性来指定调用任意公共方法。

Interceptor (拦截器)

拦截器是 Struts 2 的精髓,它实现了 AOP (面向切面编程) 的思想,拦截器可以在 Action 执行之前和之后插入代码,用于处理通用的横切逻辑,如:

  • 权限检查
  • 日志记录
  • 请求参数封装
  • 数据验证

Struts 2 提供了大量的内置拦截器(在 struts-default.xml 中定义),并默认形成一个拦截器栈,你也可以自定义拦截器。

Result (结果)

当 Action 方法执行完毕后,会返回一个字符串(如 "success", "error"),框架会根据这个字符串在 struts.xml 中查找对应的 <result> 标签,然后执行相应的操作。

  • dispatcher: 默认类型,用于转发到 JSP 或 HTML 页面。
  • redirect: 用于重定向到另一个 URL。
  • stream: 用于下载文件。
  • json: 用于返回 JSON 数据,常用于 AJAX 请求。

OGNL (Object-Graph Navigation Language)

OGNL 是一种强大的表达式语言,用于在视图中访问 Action 的属性,它比 JSP 的 EL 表达式更强大。

  • 访问属性:<s:property value="name"/> (等同于 action.getName())
  • 访问对象方法:<s:property value="name.toUpperCase()"/>
  • 访问静态方法:<s:property value="@java.lang.Math@random()"/>
  • 访问 List/Map:<s:property value="users[0].name"/>

ValueStack (值栈)

值栈是 Struts 2 的数据核心,它是一个栈结构,存放了 Action 的对象和临时变量,在 JSP 页面中,OGNL 表达式默认从值栈的栈顶开始查找数据,当你在 Action 中设置一个属性(如 setName()),这个属性就会被压入值栈,从而在视图中可以被直接访问。


常用标签库

Struts 2 提供了丰富的标签库,极大地简化了视图开发,使用前必须引入:<%@ taglib prefix="s" uri="/struts-tags" %>

数据标签

  • <s:property value="expression">: 获取并显示值栈中表达式的值。
  • <s:iterator value="collection">: 遍历集合(List, Set, Map)。
    <s:iterator value="users">
        <p>姓名: <s:property value="name"/>, 年龄: <s:property value="age"/></p>
    </s:iterator>

UI 标签

UI 标签会自动生成 HTML 代码,并会自动从值栈中获取数据。

  • <s:form action="someAction">: 创建表单。
  • <s:textfield name="username" label="用户名">: 创建文本输入框。
  • <s:password name="password" label="密码">: 创建密码输入框。
  • <s:submit value="提交">: 创建提交按钮。

控制标签

  • <s:if test="condition">: 条件判断。
  • <s:elseif test="anotherCondition">: 否则如果。
  • <s:else>: 否则。
    <s:if test="age > 18">
        <p>成年人</p>
    </s:if>
    <s:else>
        <p>未成年人</p>
    </s:else>

数据接收与验证

Struts 2 提供了非常方便的数据接收机制。

属性驱动接收

这是最简单的方式,在 Action 类中定义属性,并提供 getter/setter,表单中 input 标签的 name 属性值必须和 Action 中的属性名一致。

Action:

public class UserAction {
    private String username;
    private int age;
    // getter and setter...
    public String execute() {
        System.out.println("Username: " + username + ", Age: " + age);
        return "success";
    }
}

JSP:

<s:form action="saveUser">
    <s:textfield name="username" label="用户名"/>
    <s:textfield name="age" label="年龄"/>
    <s:submit/>
</s:form>

模型驱动接收

如果表单数据需要封装到一个对象中,可以使用模型驱动。

  1. Action 实现 ModelDriven 接口。
  2. 实现 getModel() 方法,返回你的模型对象。

Action:

import com.opensymphony.xwork2.ModelDriven;
public class UserAction implements ModelDriven<User> {
    private User user = new User(); // 必须手动实例化
    @Override
    public User getModel() {
        return user;
    }
    public String execute() {
        System.out.println("Username: " + user.getUsername() + ", Age: " + user.getAge());
        return "success";
    }
}

JSP: (和属性驱动一样,name 对应模型对象的属性)

<s:form action="saveUser">
    <s:textfield name="username" label="用户名"/> <!-- 对应 user.getUsername() -->
    <s:textfield name="age" label="年龄"/>      <!-- 对应 user.getAge() -->
    <s:submit/>
</s:form>

验证

可以在 Action 类所在目录下创建一个 ActionName-validation.xml 文件来进行声明式验证。

User.java:

public class User {
    private String username;
    private int age;
    // getter and setter...
}

User-validation.xml:

<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.3//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
    <field name="username">
        <field-validator type="requiredstring">
            <message>用户名不能为空</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="min">2</param>
            <param name="max">10</param>
            <message>用户名长度必须在2到10之间</message>
        </field-validator>
    </field>
    <field name="age">
        <field-validator type="int">
            <param name="min">18</param>
            <param name="max">100</param>
            <message>年龄必须在18到100之间</message>
        </field-validator>
    </field>
</validators>

如果验证失败,Struts 2 会自动返回 input 视图,并将错误信息存放在值栈中,可以通过 <s:fielderror> 标签显示。


文件上传

Struts 2 内置了文件上传功能,非常简单。

  1. Action 类:接收 File 对象、文件名和文件类型。

    public class FileUploadAction {
        private File file;
        private String fileFileName;
        private String fileContentType;
        // getter and setter...
        public String execute() throws Exception {
            // 将文件保存到服务器
            String filePath = "C:/uploads/";
            FileUtils.copyFile(file, new File(filePath + fileFileName));
            return "success";
        }
    }
  2. JSP 表单:必须设置 enctype="multipart/form-data"

    <s:form action="upload" method="post" enctype="multipart/form-data">
        <s:file name="file" label="选择文件"/>
        <s:submit value="上传"/>
    </s:form>
  3. struts.xml:配置文件上传拦截器。

    <action name="upload" class="com.example.action.FileUploadAction">
        <!-- 确保文件上传拦截器在栈中 -->
        <interceptor-ref name="fileUpload">
            <param name="allowedTypes">image/jpeg,image/png,image/gif</param>
            <param name="maximumSize">1048576</param> <!-- 1MB -->
        </interceptor-ref>
        <interceptor-ref name="defaultStack"/>
        <result name="success">/upload_success.jsp</result>
        <result name="input">/upload_form.jsp</result>
    </action>

总结与展望

通过本教程,你已经掌握了 Struts 2 的基本用法,包括环境搭建、MVC 流程、Action、配置、标签库、数据接收和验证等核心概念。

Struts 2 的未来:如前所述,Struts 2 已不再是主流,对于新的 Web 项目,强烈推荐使用 Spring Boot + Spring MVC 或现代化的 QuarkusMicronaut 等框架,这些框架在性能、易用性、社区支持和安全性方面都更有优势。

理解 Struts 2 的设计思想和核心机制(如 MVC、拦截器、值栈)对于成为一名全面的 Java Web 开发者来说是非常有益的,它为你理解更现代的框架打下了坚实的基础。

分享:
扫描分享到社交APP
上一篇
下一篇