杰瑞科技汇

Java Struts教程该怎么学?入门到实践怎么走?

Java Struts 教程:从入门到实践

目录

  1. 什么是 Struts?
  2. Struts 2 的核心优势
  3. 环境准备
  4. 创建第一个 Struts 2 应用:Hello World
    • 1 创建 Web 项目
    • 2 添加 Struts 2 依赖
    • 3 配置 web.xml
    • 4 创建 Action 类
    • 5 创建视图(JSP)
    • 6 配置 Struts 2 (struts.xml)
    • 7 部署与运行
  5. 深入理解 Struts 2 架构
    • 1 核心组件:FilterDispatcher (Struts 2.5+) / StrutsPrepareAndExecuteFilter
    • 2 核心组件:Action
    • 3 核心组件:Interceptor (拦截器)
    • 4 核心组件:Result (结果)
    • 5 核心组件:ValueStack (值栈)
  6. 常用功能详解
    • 1 数据封装 (接收表单数据)
    • 2 OGNL 表达式
    • 3 拦截器配置与使用
    • 4 文件上传
  7. 总结与资源

什么是 Struts?

Struts 是一个开源的、用于创建企业级 Java Web 应用程序的 MVC (Model-View-Controller) 框架,它的主要目的是将应用程序的不同部分(业务逻辑、数据、展示)解耦,使开发更加模块化和可维护。

Java Struts教程该怎么学?入门到实践怎么走?-图1
(图片来源网络,侵删)
  • Struts 1:早期的经典框架,曾是 Java Web 开发的霸主,但其设计(如基于 FormBean)在今天看来有些过时。
  • Struts 2:目前的主流版本。需要特别注意的是,Struts 2 并非 Struts 1 的升级版,它是在另一个名为 WebWork 的框架基础上发展而来的,因此其架构和设计理念与 Struts 1 有很大不同。

本教程将专注于 Struts 2

Struts 2 的核心优势

  1. 清晰的 MVC 架构:严格分离了业务逻辑、数据模型和用户界面。
  2. 强大的拦截器机制:通过拦截器,可以轻松实现如日志、权限验证、数据预处理等横切关注点,无需在 Action 中编写重复代码。
  3. 简单易用的 Action 开发:Action 不需要继承任何父类,只需实现一个方法(通常是 execute),或者使用 POJO (Plain Old Java Object) 作为 Action,非常灵活。
  4. 强大的 OGNL 表达式语言:在视图中可以直接访问 Action 的属性、调用方法,操作集合和 Map,使页面与后端交互非常方便。
  5. 丰富的标签库:提供了大量 JSP 标签(如 <s:form>, <s:textfield>, <s:if>),简化了页面的开发。
  6. 插件化:拥有大量成熟的插件,如用于 REST 开发、Convention Plugin(约定优于配置)、JSON 插件等。

环境准备

在开始之前,请确保你已经安装并配置好了以下环境:

  • JDK: 版本 8 或更高版本。
  • Web 服务器: 如 Apache Tomcat 9.x 或更高版本。
  • IDE: Eclipse for Enterprise Java and Web Developers 或 IntelliJ IDEA。
  • 构建工具 (推荐): Maven 或 Gradle,用于管理项目依赖。

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

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

1 创建 Web 项目

在你的 IDE 中,创建一个新的 Dynamic Web Project (在 Maven 中,可使用 maven-archetype-webapp 模板)。

Java Struts教程该怎么学?入门到实践怎么走?-图2
(图片来源网络,侵删)

2 添加 Struts 2 依赖

最简单的方式是使用 Maven,在 pom.xml 文件中添加以下依赖:

<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>
        <scope>test</scope>
    </dependency>
    <!-- JSP 和 Servlet API (Tomcat 提供的版本不满足,可以显式添加) -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

如果你不使用 Maven,需要手动下载 struts2-core-2.x.x.jar 以及其依赖的 JAR 包,并放入项目的 WEB-INF/lib 目录下。

3 配置 web.xml

web.xml 是 Web 应用的部署描述符,我们需要在这里配置一个 Filter 来拦截所有请求,并将其交给 Struts 2 框架处理。

src/main/webapp/WEB-INF/web.xml 中添加以下内容:

Java Struts教程该怎么学?入门到实践怎么走?-图3
(图片来源网络,侵删)
<?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>
        <filter-name>struts2</filter-name>
        <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 类

Action 是 Struts 2 的核心,它处理用户请求并返回一个结果字符串,框架根据这个字符串来决定渲染哪个视图。

src/main/java 下创建一个包,com.example.action,然后创建 HelloWorldAction.java

package com.example.action;
public class HelloWorldAction {
    private String name;
    private String message;
    // 这是默认执行的方法
    public String execute() {
        this.message = "Hello, " + this.name + "!";
        return "success"; // 返回一个逻辑视图名
    }
    // Getter 和 Setter 方法 (必须提供,用于 OGNL 访问和值栈注入)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

5 创建视图

视图负责展示数据,我们在 src/main/webapp 下创建 hello.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>Struts 2 Hello World</title>
</head>
<body>
    <h2>Hello World</h2>
    <!-- 使用 Struts 2 的表单标签 -->
    <s:form action="hello">
        <s:textfield name="name" label="Your Name" />
        <s:submit value="Submit" />
    </s:form>
    <!-- 显示从 Action 传来的消息 -->
    <s:property value="message" />
</body>
</html>

注意<%@ taglib prefix="s" uri="/struts-tags" %> 是引入 Struts 2 的标签库。

6 配置 Struts 2 (struts.xml)

struts.xml 是 Struts 2 的核心配置文件,它定义了 Action 如何与 URL 映射,以及 Action 的返回结果对应哪个 JSP 页面。

src/main/resources 目录下创建 struts.xml 文件(这个目录会自动被部署到 WEB-INF/classes 下)。

<?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="hello" namespace="/" extends="struts-default">
        <!-- 定义一个 Action,name="hello" 将作为 URL 的一部分 -->
        <action name="hello" class="com.example.action.HelloWorldAction">
            <!-- 定义结果,name="success" 对应 Action execute() 方法的返回值 -->
            <!-- type="dispatcher" 表示使用 RequestDispatcher 转发,默认值 -->
            <result name="success">/hello.jsp</result>
        </action>
    </package>
</struts>

7 部署与运行

  1. 将你的 Web 项目部署到 Tomcat 服务器。
  2. 启动 Tomcat。
  3. 在浏览器中访问 http://localhost:8080/你的项目名/hello.action
  4. 在输入框中输入你的名字,"Struts",然后点击 Submit。
  5. 页面会跳转到 hello.jsp,并显示 "Hello, Struts!"。

至此,你的第一个 Struts 2 应用就成功运行了!

深入理解 Struts 2 架构

1 核心组件:FilterDispatcher (Struts 2.5+)

web.xml 中配置的 StrutsPrepareAndExecuteFilter 是整个框架的入口,它像一个总指挥,负责拦截请求,并根据 struts.xml 的配置,将请求分发给相应的 Action。

2 核心组件:Action

Action 是业务逻辑的载体,它是一个普通的 Java 类,不需要继承任何类,当请求到达时,Struts 2 会使用反射创建 Action 的实例,然后调用其 execute() 方法(或者你通过 method 属性指定的方法)。

Action 的返回值(如 "success", "error")并不直接代表一个页面,而是逻辑视图名,由 struts.xml 中的 <result> 标签来决定最终渲染哪个物理页面。

3 核心组件:Interceptor (拦截器)

拦截器是 Struts 2 最强大的功能之一,它是一个可以在 Action 执行前后插入代码的 AOP (面向切面编程) 实现。

  • 工作流程:请求 -> 拦截器链 -> Action -> 拦截器链 -> 结果
  • 内置拦截器:Struts 2 提供了大量功能强大的内置拦截器,如:
    • params: 负责将请求参数注入到 Action 的属性中(数据封装)。
    • modelDriven: 将请求参数直接注入到 Model 对象中。
    • validation: 负责执行输入验证。
    • prepare: 在 Action 执行前做一些准备工作。
  • 自定义拦截器:你可以轻松编写自己的拦截器来复用通用逻辑,如用户登录验证、日志记录等。

4 核心组件:Result (结果)

<result> 定义了 Action 执行完成后,下一步要做什么,Struts 2 支持多种 Result 类型:

  • dispatcher (默认): 服务器端转发,用于跳转到 JSP。
  • redirect: 客户端重定向,可以防止表单重复提交。
  • redirectAction: 重定向到另一个 Action。
  • stream: 用于下载文件。
  • json: 用于返回 JSON 数据,常用于 AJAX 请求。

5 核心组件:ValueStack (值栈)

值栈是 Struts 2 的数据核心,是一个数据存储区域,它是一个栈结构,存放了 Action 的实例以及 Action 的所有属性。

  • OGNL:OGNL (Object-Graph Navigation Language) 是 Struts 2 默认的表达式语言,它通过访问值栈来获取和设置数据。
  • JSP 中的访问:在 JSP 页面中,<s:property value="name"/> 会自动从值栈的栈顶开始查找 name 属性,在 Action 中设置的 namemessage 属性都可以被直接访问。

常用功能详解

1 数据封装

Struts 2 提供了非常方便的数据封装机制,可以将表单数据自动填充到 Action 的属性中,这主要依靠 params 拦截器实现。

  • 属性驱动:如我们上面的例子,在 Action 中提供属性的 getter/setter。
  • 模型驱动:如果你的 Action 需要接收一个复杂的对象,可以实现 ModelDriven 接口。
// Action 类
public class UserAction implements ModelDriven<User> {
    private User user = new User(); // 必须手动实例化
    @Override
    public User getModel() {
        return user;
    }
    public String execute() {
        // user 对象已经被填充了表单数据
        System.out.println("Username: " + user.getUsername());
        return "success";
    }
}

对应的 JSP 表单:

<s:form action="user">
    <s:textfield name="username" label="Username" /> <!-- name 必须与 User 对象的属性名一致 -->
    <s:password name="password" label="Password" />
    <s:submit />
</s:form>

2 OGNL 表达式

OGNL 是 Struts 2 的灵魂,在 JSP 中通过 、、 符号来使用。

  • 访问属性<s:property value="user.name" />
  • 调用方法<s:property value="user.toUpperCaseName()" />
  • 访问静态方法<s:property value="@com.example.utils.DateUtils@formatNow()" />
  • 访问集合/Map
      <s:iterator value="users" var="u">
          <s:property value="#u.name" />
      </s:iterator>
  • 符号:用于访问上下文对象,如 #request, #session, #application
  • 符号:在属性值中强制解析 OGNL。
  • 符号:在国际化或配置文件中解析值。

3 拦截器配置与使用

你可以在 struts.xml 中为某个 Action 或整个 Package 指定拦截器。

<package name="myPackage" extends="struts-default">
    <!-- 定义拦截器栈 -->
    <interceptors>
        <interceptor name="myLoggingInterceptor" class="com.example.interceptor.LoggingInterceptor"/>
        <interceptor-stack name="myStack">
            <interceptor-ref name="defaultStack"/> <!-- 必须包含默认拦截器栈 -->
            <interceptor-ref name="myLoggingInterceptor"/>
        </interceptor-stack>
    </interceptors>
    <!-- 设置默认的拦截器栈 -->
    <default-interceptor-ref name="myStack"/>
    <action name="admin" class="com.example.action.AdminAction">
        <interceptor-ref name="myStack"/>
        <result name="success">/admin.jsp</result>
    </action>
</package>

4 文件上传

Struts 2 内置了强大的文件上传功能。

  1. Action 类:使用 File 类型接收文件,String 类型接收文件名。
    private File upload;
    private String uploadContentType;
    private String uploadFileName;
    // ... getter/setter
  2. JSP 表单<s:file> 标签,并设置 enctype="multipart/form-data"
    <s:form action="upload" method="post" enctype="multipart/form-data">
        <s:file name="upload" label="Select a File" />
        <s:submit />
    </s:form>
  3. struts.xml:需要配置一个允许上传文件大小的常量。
    <constant name="struts.multipart.maxSize" value="10485760" /> <!-- 10MB -->

总结与资源

Struts 2 是一个成熟、功能强大且设计优雅的 MVC 框架,虽然近年来 Spring MVC 和其他框架(如 Play, Micronaut)的兴起使其市场份额有所下降,但 Struts 2 的核心思想(尤其是拦截器和值栈)对后来的框架产生了深远影响。

优点

  • 解耦度高:MVC 分层清晰。
  • 扩展性强:拦截器和插件机制非常灵活。
  • 开发效率高:标签库和 OGNL 大大简化了视图层开发。

缺点

  • 学习曲线:概念较多(值栈、拦截器栈等),需要时间掌握。
  • 配置繁琐:相比 Spring MVC 的注解驱动,XML 配置略显繁琐(但可通过 Convention Plugin 改善)。
  • 历史包袱:曾曝出过严重的安全漏洞(如 CVE-2025-5638),虽然已修复,但影响了声誉。

推荐资源

希望这份教程能帮助你顺利入门 Struts 2!

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