Struts2 工作流程详解:从请求到响应的完整生命周期
Struts2 作为基于 MVC 模式的 Web 框架,其核心工作流程围绕拦截器链和Action 处理展开,通过分层设计实现请求的接收、处理与响应。以下是对其工作流程的详细拆解:
Struts2 工作流程总览
Struts2 的工作流程可概括为 “拦截器预处理→Action 业务处理→拦截器后处理→结果响应”,具体步骤如下:
- 客户端发送请求(如
http://localhost:8080/struts/userAction/test.action); - 请求被核心过滤器
StrutsPrepareAndExecuteFilter拦截; - 框架解析请求,匹配
struts.xml中对应的 Action 配置; - 请求经过拦截器链的预处理(如参数封装、校验、日志记录等);
- 创建 Action 实例,调用指定方法(如
test())执行业务逻辑; - Action 返回结果标识(如
"success"); - 框架根据结果标识匹配
struts.xml中的<result>,生成响应视图; - 请求再次经过拦截器链的后处理(如资源清理、事务提交等);
- 响应结果返回给客户端。
核心步骤详解
1. 请求拦截与初始化(StrutsPrepareAndExecuteFilter)
- 过滤器作用:
StrutsPrepareAndExecuteFilter是 Struts2 的入口,负责:- 初始化框架环境(加载
struts.xml、struts-default.xml等配置); - 将请求封装为
ActionContext(存储请求参数、Session 等上下文信息); - 触发后续的拦截器链和 Action 调用。
- 初始化框架环境(加载
- 关键对象:
ActionMapping:根据请求路径匹配struts.xml中的 Action 配置(包括namespace、action name、class、method等)。
2. 拦截器链处理(核心设计)
Struts2 的核心优势在于拦截器机制,通过可插拔的拦截器实现通用功能(如参数注入、权限校验),避免代码重复。
- 执行流程:
- 拦截器链按配置顺序执行
intercept()方法,对请求进行预处理(如ParametersInterceptor负责将请求参数注入 Action 属性); - 所有拦截器预处理完成后,才会调用 Action 的业务方法;
- Action 执行完毕后,拦截器链按相反顺序执行后处理逻辑(如
ExceptionMappingInterceptor处理异常)。
- 拦截器链按配置顺序执行
- 默认拦截器:
继承struts-default包后,会自动启用默认拦截器链,包括:params:注入请求参数到 Action;validation:执行数据校验;workflow:检查校验结果,若失败则跳转至输入页面。
3. Action 实例化与业务处理
- 实例创建:Struts2 为每个请求创建一个 Action 实例(非单例),通过反射调用无参构造器初始化。
- 参数注入:拦截器
params通过 OGNL 表达式将请求参数(如user.name=张三)注入 Action 的属性(需提供 getter/setter)。 - 方法调用:根据
struts.xml中method属性(默认execute())调用对应方法,执行业务逻辑(如数据库操作、业务计算等)。 - 结果返回:Action 方法返回
String类型的结果标识(如"success"、"error"),用于匹配后续的视图。
4. 结果视图渲染(<result>处理)
- 结果匹配:框架根据 Action 返回的结果标识,查找
struts.xml中对应的<result>标签,确定视图类型(如dispatcher、redirect)和路径。 - 视图类型:
dispatcher(默认):服务器内部转发,地址栏不变;redirect:重定向到页面或 URL,地址栏变化;redirectAction:重定向到另一个 Action;stream:用于文件下载等二进制响应。
5. 拦截器后处理与响应返回
- Action 执行和视图渲染完成后,请求按相反顺序再次经过拦截器链,执行后处理逻辑(如日志记录、资源释放、事务提交等)。
- 最终响应结果通过
HttpServletResponse返回给客户端,完成整个请求生命周期。
工作流程图解
1 | 客户端请求 → [StrutsPrepareAndExecuteFilter] → 解析请求,匹配Action配置 |
关键设计亮点
- 拦截器解耦:通用功能(如参数处理、校验)通过拦截器实现,与业务逻辑分离,便于复用和扩展;
- Action 无状态:每个请求对应一个 Action 实例,避免线程安全问题;
- 配置驱动:通过
struts.xml集中管理请求映射和视图跳转,减少硬编码; - 灵活的结果处理:支持多种视图类型,适配不同场景(页面跳转、文件下载等)。
常见问题与优化
- 拦截器顺序:拦截器的执行顺序由配置决定,需注意依赖关系(如
validation需在params之后执行,确保参数已注入); - Action 性能:避免在 Action 中编写复杂业务逻辑,应委托给 Service 层处理;
- 结果缓存:对于静态资源或高频请求,可通过拦截器实现缓存机制,减少重复处理