浅谈Struts2请求解析过程
字数 1750 2025-08-06 08:34:54

Struts2请求解析过程详解

0x00 前言

Struts2框架通过配置过滤器来拦截和处理用户请求,核心过滤器是StrutsPrepareAndExecuteFilter,它负责将请求分配给对应的Action并进行参数赋值。

过滤器配置示例

<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>

0x01 Struts2请求解析过程

1.1 关键解析类

1.1.1 StrutsPrepareAndExecuteFilter

核心处理流程在doFilter方法中:

  1. 获取HttpServletRequestHttpServletResponse对象
  2. 检查排除的URL模式
  3. 检查是否为静态资源
  4. 处理非静态资源请求:
    • 设置请求编码和区域设置
    • 创建ActionContext
    • 分配Dispatcher
    • 包装和准备请求
    • 查找ActionMapping
    • 执行对应Action或传递到下一个过滤器
  5. 执行请求清理操作

1.1.2 RequestUtils

负责URI路径处理:

  • getUri方法获取请求URI:

    • 首先尝试从javax.servlet.include.servlet_path属性获取
    • 否则调用getServletPath获取
    • 最后使用request.getRequestURI()并去除上下文路径
  • getServletPath方法处理路径匹配:

    • 处理servletPathrequestUri不匹配的情况
    • 截取相对于上下文路径的部分

1.2 关键流程

1.2.1 寻找ActionMapping

PrepareOperations#findActionMapping流程:

  1. 尝试从请求缓存中获取ActionMapping
  2. 未找到则通过DefaultActionMapper#getMapping创建:
    • 获取并处理URI路径(去除分号后内容和扩展名)
    • 解析名称和命名空间
    • 处理特殊参数
    • 解析Action名称

1.2.2 缺省后缀

默认处理的后缀定义在default.properties中:

struts.action.extension=action,

可通过struts.xml修改:

<constant name="struts.action.extension" value="do,action"/>

1.2.3 parseNameAndNamespace解析

URL路径结构:namespace + Action + extension

解析逻辑:

  1. 查找最后一个斜杠位置
  2. 处理不同斜杠位置情况:
    • 无斜杠:namespace为空,name为URI
    • 斜杠在首位:namespace为"/",name为剩余部分
    • alwaysSelectFullNamespace为true时整个URI作为namespace
  3. 通过配置管理器确定命名空间:
    • 迭代package配置
    • 匹配prefix和namespace
  4. 处理allowSlashesInActionNames设置
  5. 设置最终的namespace和name

1.3 其他

1.3.1 FilterDispatcher

Struts2早期版本(2.0.x-2.1.2)的核心过滤器,2.1.3后被StrutsPrepareAndExecuteFilter取代。

0x02 区分Spring与Struts2

2.1 缺省后缀

  • Struts2:默认处理无后缀或.action结尾的请求
  • Spring:需要启用SuffixPatternMatch模式才能类似处理

2.2 路径匹配容错机制

  • Struts2:namespace后可加任意目录仍能匹配Action
  • Spring:无此特性

2.3 路径规范化处理

  • Struts2:处理../等路径
  • Spring Boot ≤2.3.0:会规范化路径
  • Spring Boot >2.3.0:不处理跨目录字符,返回404

2.4 尾部斜杠处理

  • Spring:可配置匹配尾部斜杠
  • Struts2:不考虑尾部斜杠,可能导致404

2.5 Struts2特有静态资源

Struts2 jar包中包含特有静态文件,如:

  • /struts/domTT.css (2.5.25)
  • 其他版本也有特定文件

访问这些资源可帮助识别Struts2框架。


这篇文档详细总结了Struts2请求解析的核心流程,包括关键类、处理步骤以及与Spring框架的区别点,涵盖了原文所有关键技术细节。

Struts2请求解析过程详解 0x00 前言 Struts2框架通过配置过滤器来拦截和处理用户请求,核心过滤器是 StrutsPrepareAndExecuteFilter ,它负责将请求分配给对应的Action并进行参数赋值。 过滤器配置示例 0x01 Struts2请求解析过程 1.1 关键解析类 1.1.1 StrutsPrepareAndExecuteFilter 核心处理流程在 doFilter 方法中: 获取 HttpServletRequest 和 HttpServletResponse 对象 检查排除的URL模式 检查是否为静态资源 处理非静态资源请求: 设置请求编码和区域设置 创建 ActionContext 分配 Dispatcher 包装和准备请求 查找 ActionMapping 执行对应Action或传递到下一个过滤器 执行请求清理操作 1.1.2 RequestUtils 负责URI路径处理: getUri 方法获取请求URI: 首先尝试从 javax.servlet.include.servlet_path 属性获取 否则调用 getServletPath 获取 最后使用 request.getRequestURI() 并去除上下文路径 getServletPath 方法处理路径匹配: 处理 servletPath 与 requestUri 不匹配的情况 截取相对于上下文路径的部分 1.2 关键流程 1.2.1 寻找ActionMapping PrepareOperations#findActionMapping 流程: 尝试从请求缓存中获取 ActionMapping 未找到则通过 DefaultActionMapper#getMapping 创建: 获取并处理URI路径(去除分号后内容和扩展名) 解析名称和命名空间 处理特殊参数 解析Action名称 1.2.2 缺省后缀 默认处理的后缀定义在 default.properties 中: 可通过 struts.xml 修改: 1.2.3 parseNameAndNamespace解析 URL路径结构: namespace + Action + extension 解析逻辑: 查找最后一个斜杠位置 处理不同斜杠位置情况: 无斜杠:namespace为空,name为URI 斜杠在首位:namespace为"/",name为剩余部分 alwaysSelectFullNamespace 为true时整个URI作为namespace 通过配置管理器确定命名空间: 迭代package配置 匹配prefix和namespace 处理 allowSlashesInActionNames 设置 设置最终的namespace和name 1.3 其他 1.3.1 FilterDispatcher Struts2早期版本(2.0.x-2.1.2)的核心过滤器,2.1.3后被 StrutsPrepareAndExecuteFilter 取代。 0x02 区分Spring与Struts2 2.1 缺省后缀 Struts2:默认处理无后缀或 .action 结尾的请求 Spring:需要启用 SuffixPatternMatch 模式才能类似处理 2.2 路径匹配容错机制 Struts2:namespace后可加任意目录仍能匹配Action Spring:无此特性 2.3 路径规范化处理 Struts2:处理 ../ 等路径 Spring Boot ≤2.3.0:会规范化路径 Spring Boot >2.3.0:不处理跨目录字符,返回404 2.4 尾部斜杠处理 Spring:可配置匹配尾部斜杠 Struts2:不考虑尾部斜杠,可能导致404 2.5 Struts2特有静态资源 Struts2 jar包中包含特有静态文件,如: /struts/domTT.css (2.5.25) 其他版本也有特定文件 访问这些资源可帮助识别Struts2框架。 这篇文档详细总结了Struts2请求解析的核心流程,包括关键类、处理步骤以及与Spring框架的区别点,涵盖了原文所有关键技术细节。