Struts2 框架的请求处理逻辑通常由 struts.xml 配置文件集中定义。该文件负责描述请求如何被解析、动作类如何被调用、执行完成后页面如何跳转,以及框架在运行过程中需要遵循的基础参数。对于维护传统企业级 Web 应用而言,理解 struts.xml 的层级结构和核心控制器的接入方式,是判断请求是否进入框架、动作是否被正确执行的关键。

struts.xml 的整体结构与配置组织方式
struts.xml 的根节点是 <struts>,所有常量、包、动作和结果配置都必须位于该节点内部。文件开头通常会声明 XML 版本和 DOCTYPE,其中 DOCTYPE 会引用 Struts2 对应版本的 DTD 文档,用于约束配置文件的语法结构。若根节点缺失、闭合不完整,或者 DOCTYPE 与框架版本不一致,框架在启动或解析配置时都可能报错。
从工程角度看,struts.xml 并不只是简单罗列动作映射,而是把全局参数、分组规则、动作映射和结果跳转分层组织。全局参数通过常量定义,分组规则通过包定义,动作映射通过动作定义,结果跳转通过结果定义。这种分层方式可以让多个模块共享默认拦截器、命名空间和结果类型,也能让不同业务模块保持独立,避免所有动作堆在同一个命名空间下造成路径冲突。
一个最小可用的 struts.xml 只需要保留 XML 声明、DOCTYPE 声明和根节点即可。后续所有配置都可以在此基础上逐步补充。将配置拆分为多个包后,每个包都可以拥有自己的命名空间,从而把用户、订单、权限等路径前缀划分清楚,也便于后续维护和扩展。
<?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>
<!-- 配置内容写在这里 -->
</struts>
常量、包、Action 与 Result 的协作关系
在 struts.xml 中,常量、包、动作和结果并不是孤立存在的,它们共同完成一次请求的处理流程。常量决定框架的基础行为,包决定动作归属和可继承的配置,动作决定请求由哪个 Java 类和方法处理,结果决定动作返回值对应到哪个页面或后续动作。理解这四者的关系,才能准确判断请求最终落在哪个页面。
常量配置适合放置那些影响全局的参数,例如请求编码、开发模式开关、请求后缀等。开发阶段开启开发模式后,配置文件变化更容易被及时感知,便于排查映射问题;生产环境中则通常需要关闭,以减少额外开销并提升稳定性。
常量配置
常见常量包括编码、开发模式和请求后缀。编码用于处理中文参数和页面输出,开发模式用于调试,请求后缀用于限定哪些 URL 会被 Struts2 识别。若请求后缀配置过窄,部分 URL 可能无法进入框架;若配置过宽,也可能让框架处理本应由静态资源或其他组件处理的请求。
<?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>
<!-- 设置编码为 UTF-8 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 开启开发模式 -->
<constant name="struts.devMode" value="true"/>
<!-- 指定请求后缀 -->
<constant name="struts.action.extension" value="action,do"/>
</struts>
包配置
包是 Struts2 配置分组的基本单位。通过 extends 属性继承 struts-default,可以获得框架默认提供的拦截器栈和结果类型。namespace 用于区分不同包下的同名动作,name 则是包在配置文件中的唯一标识。合理设计包结构,可以让登录、注册、订单、权限等模块各自独立,同时共享默认行为。
| 属性名 | 作用 |
|---|---|
name | 包的唯一标识,必填 |
extends | 继承的父包,通常继承 struts-default 获取默认拦截器栈 |
namespace | 包的命名空间,用于区分不同包下的同名动作 |
<?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>
<package name="default" extends="struts-default" namespace="/">
<!-- 该包下的 action 配置 -->
</package>
</struts>
Action 与 Result 配置
<action> 标签把请求路径映射到具体动作类和方法。name 与 namespace 组合形成请求路径,class 指定处理类,method 指定执行方法。<result> 标签则根据动作方法的返回值决定下一步跳转。默认结果类型通常是转发到 JSP 页面,也可以配置为重定向、链式调用等。
<?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>
<package name="default" extends="struts-default" namespace="/">
<action name="login" class="com.ipipp.UserAction" method="login">
<result name="success">/success.jsp</result>
<result name="error" type="redirect">/login.jsp</result>
</action>
</package>
</struts>
从请求流程看,用户访问某个带指定后缀的地址后,框架先根据命名空间和动作名称找到对应动作,再调用 class 和 method 指定的处理方法。方法返回字符串后,框架在结果列表中查找同名结果,并按 type 执行转发或重定向。若返回字符串没有对应结果,页面通常会报错,因此返回值和结果标识必须保持一致。
Struts2 核心控制器与过滤器配置
struts.xml 描述的是框架内部的处理规则,而真正让请求进入 Struts2 的核心控制器是 StrutsPrepareAndExecuteFilter。该过滤器在 web.xml 中注册后,会拦截匹配的请求,完成参数准备、上下文构建、动作执行和结果渲染等准备工作。没有这个过滤器,struts.xml 中的动作映射不会生效。
在 Servlet 容器中,过滤器通常按照声明顺序执行。Struts2 核心过滤器一般负责处理业务请求,因此需要保证它覆盖目标 URL,同时避免被静态资源过滤器或其他安全过滤器提前拦截。若项目中存在多个过滤器,建议把 Struts2 核心过滤器放在较靠后的位置,让资源过滤、编码过滤、安全过滤先完成各自职责。
<?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_3_1.xsd"
version="3.1">
<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>
配置时需要注意三个细节:第一,过滤器类名要与项目使用的 Struts2 版本匹配,不同版本的包路径可能不同;第二,<url-pattern> 通常配置为 /*,确保带指定后缀的请求都能被拦截;第三,<filter> 与 <filter-mapping> 中的 filter-name 必须一致,否则映射不会生效。
- 过滤器类名需要与 Struts2 版本对应,避免类路径不存在。
- 拦截范围通常配置为
/*,保证业务请求能够进入框架。 - 多个过滤器共存时,需要关注执行顺序,核心过滤器不宜过早被其他过滤器绕过。
从运行过程看,核心过滤器会先准备请求上下文,再依据 struts.xml 找到动作并执行,最后根据结果类型输出页面。它相当于 Struts2 的入口,struts.xml 则是入口背后的路由表。两者配合正确,请求才能完成从地址到动作再到页面的完整链路。
常见配置问题排查与完整示例
实际开发中,Struts2 配置问题大多集中在三类位置:DTD 与版本不匹配、动作类路径错误、过滤器映射不完整。DTD 不匹配会导致配置文件无法通过校验;动作类路径错误会导致框架找不到处理类;过滤器映射不完整则会让请求根本没有进入 Struts2。排查时建议从外到内逐层确认,先看 web.xml,再看 struts.xml,最后看动作类本身。
对于 DTD 问题,应检查 DOCTYPE 中声明的版本号是否与项目依赖的 Struts2 版本一致。对于动作类问题,应检查 class 属性是否写全包名,method 是否存在于该类中,并且方法返回值是否有对应结果。对于过滤器问题,应检查 filter-name、filter-class 和 url-pattern 是否完整,是否被其他过滤器提前消费。
检查 DOCTYPE 声明是否与 Struts2 版本一致,避免配置文件解析失败。
检查动作的
class和method是否真实存在,避免找不到处理类或处理方法。检查核心过滤器的
url-pattern是否覆盖目标请求,避免请求未进入框架。
这里给出一个完整示例,把常量、包、动作和结果放在同一个配置文件中。该示例使用 /user 命名空间,定义登录和注册两个动作,并分别配置成功后的跳转页面。
<?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.i18n.encoding" value="UTF-8"/>
<constant name="struts.devMode" value="true"/>
<constant name="struts.action.extension" value="action"/>
<!-- 包配置 -->
<package name="user" extends="struts-default" namespace="/user">
<!-- Action 配置 -->
<action name="login" class="com.ipipp.UserAction" method="login">
<result name="success">/user/success.jsp</result>
<result name="error">/user/login.jsp</result>
</action>
<action name="register" class="com.ipipp.UserAction" method="register">
<result name="success">/user/register_success.jsp</result>
</action>
</package>
</struts>
总结来看,struts.xml 的核心价值在于把请求路由、动作执行和页面跳转规则集中管理,而核心控制器的作用则是把请求交给这套配置体系。维护 Struts2 项目时,应优先保证 DTD 版本、过滤器映射、包命名空间、动作类路径和结果标识五处一致。只要这些关键点配置正确,大多数请求无法进入框架、动作无法执行或页面无法跳转的问题都能被快速定位。
Struts2struts.xml核心控制器配置指南修改时间:2026-07-12 16:51:36