1.1 Struts2 框架概述与核心特性
Struts2 是一个基于 MVC 设计模式的 Web 应用框架。它最初作为 WebWork 框架的延伸,后来吸收了 Struts1 的优点并重新设计。这个框架的核心目标是简化企业级 Java Web 应用的开发过程。
Struts2 的核心特性包括拦截器机制、OGNL 表达式支持和插件体系。拦截器让开发者能够在请求处理的不同阶段插入自定义逻辑。OGNL 表达式则提供了在视图和控制器之间数据传递的便捷方式。插件体系允许框架功能按需扩展。
我记得第一次接触 Struts2 时,最吸引我的是它的拦截器设计。这种设计让权限验证、日志记录这些横切关注点的实现变得异常简单。开发者不再需要把这些代码分散在各个业务方法里。
1.2 Struts2 与传统 Struts1 的对比分析
Struts2 和 Struts1 虽然名称相似,但架构设计存在本质区别。Struts1 的 Action 类需要继承特定的基类,而 Struts2 的 Action 可以是任意 POJO。这种设计差异使得 Struts2 的测试更加容易。
另一个显著区别在于线程模型。Struts1 的 Action 是单例的,需要考虑线程安全问题。Struts2 为每个请求创建新的 Action 实例,自然避免了多线程问题。
视图技术的支持也有很大不同。Struts1 主要依赖 JSP 和标签库,Struts2 则提供了对多种视图技术的支持,包括 FreeMarker 和 Velocity。这种灵活性在实际项目中非常实用。
1.3 Struts2 请求处理流程详解
当用户发起一个 HTTP 请求时,Struts2 的处理流程开始启动。首先,请求会经过一系列的过滤器,其中核心的是 StrutsPrepareAndExecuteFilter。这个过滤器负责初始化处理链条。
接着,请求会进入拦截器栈。拦截器按照配置顺序依次执行,完成参数准备、数据验证、文件上传等预处理工作。拦截器执行完毕后,才会调用对应的 Action 方法。
Action 方法执行完成后,返回一个结果字符串。框架根据这个结果字符串选择相应的视图进行渲染。最后,响应再次经过拦截器栈进行后处理,然后返回给用户。
这个处理流程的设计确实很优雅,每个环节都有明确的职责分工。
1.4 Struts2 与其他 MVC 框架对比
与 Spring MVC 相比,Struts2 的配置相对更加集中。Struts2 主要依赖 struts.xml 进行配置,而 Spring MVC 可以结合注解和 XML 配置。这种差异使得 Struts2 的配置更加一目了然。
在性能方面,Struts2 的拦截器机制虽然灵活,但可能带来一定的性能开销。相比之下,Spring MVC 的处理器映射机制在某些场景下可能更加高效。
学习曲线也是需要考虑的因素。Struts2 的概念相对独立,初学者可以较快上手。Spring MVC 作为 Spring 生态的一部分,需要理解更多的 Spring 核心概念。
每个框架都有其适用场景,选择时需要根据项目需求和团队技术储备综合考虑。
2.1 Struts2 环境搭建与项目配置
搭建 Struts2 开发环境需要几个基本步骤。首先确保项目中包含必要的依赖库,主要是 struts2-core 和相关依赖。使用 Maven 的话,在 pom.xml 中添加相应依赖就能自动解决版本兼容问题。
web.xml 的配置很关键。需要配置 StrutsPrepareAndExecuteFilter 作为入口过滤器。这个过滤器会拦截所有请求,交给 Struts2 框架处理。记得配置初始化参数,比如指定配置文件的位置。
struts.xml 是核心配置文件。通常放在 classpath 根目录下。这个文件定义了包结构、Action 映射、拦截器配置和结果类型。包的概念类似于 Java 包,可以组织相关的 Action 和配置。
我帮团队搭建过多次 Struts2 环境,发现版本匹配是个容易出问题的地方。不同版本的 Struts2 可能需要特定版本的依赖库。建议直接从官方文档获取推荐的依赖组合,避免自行拼凑版本。
2.2 Action 类编写与配置方法对比
Struts2 的 Action 类编写非常灵活。最基本的做法是创建一个普通 Java 类,实现 Action 接口或者直接继承 ActionSupport。ActionSupport 提供了数据验证、国际化等常用功能的默认实现。
配置 Action 主要有两种方式。传统方法是在 struts.xml 中显式配置,每个 Action 都需要定义名称、类名和结果映射。这种方式配置集中,便于整体把握项目结构。
注解配置是另一种选择。使用 @Namespace、@Action 等注解直接在 Action 类上声明配置信息。这种方式让配置和代码更贴近,修改起来比较方便。不过当 Action 数量很多时,配置信息会分散在各个类中。
两种配置方法可以混合使用。我个人的习惯是在中小型项目中使用注解,大型项目中使用 XML 配置。XML 配置在维护整体架构视图时更有优势。
2.3 拦截器与过滤器使用对比
拦截器和过滤器在 Struts2 中都扮演重要角色,但职责不同。过滤器是 Servlet 规范的概念,工作在更底层。它处理的是原始的 HTTP 请求和响应,比如字符编码转换、请求压缩。
拦截器是 Struts2 框架层面的概念。它在过滤器之后工作,专门处理 Struts2 的请求生命周期。参数封装、数据验证、文件上传这些功能都是通过拦截器实现的。
配置拦截器通常是在 struts.xml 中定义拦截器栈。默认拦截器栈已经包含了大部分常用功能。可以自定义拦截器,在特定的 Action 前或后执行特定逻辑。
实际开发中遇到过这样的场景:需要在多个 Action 执行前检查用户权限。使用自定义拦截器实现这个需求非常合适,避免了在每个 Action 中重复编写权限检查代码。
2.4 视图技术选择:JSP vs FreeMarker
JSP 是 Struts2 默认支持的视图技术,也是大多数 Java 开发者熟悉的选项。Struts2 提供了丰富的标签库来简化 JSP 开发。这些标签能够很好地与 OGNL 表达式配合,实现数据展示和表单处理。
FreeMarker 作为模板引擎,在某些方面比 JSP 更有优势。它的语法更简洁,性能通常也更好。FreeMarker 模板是纯文本,不需要编译,这在热部署场景下很方便。
选择哪种视图技术需要考虑团队技术背景。如果团队成员都熟悉 JSP,继续使用 JSP 可能更合适。如果需要更好的性能或者更喜欢简洁的模板语法,FreeMarker 值得考虑。
我在一个高并发项目中使用过 FreeMarker,模板渲染速度确实比 JSP 快不少。不过调试起来稍微麻烦一些,需要额外的工具支持。
2.5 常见配置问题与解决方案对比
类找不到是常见的配置问题。这通常是因为依赖库版本不匹配或者类路径配置错误。检查依赖树,确保所有必要的库都正确引入。使用 Maven 的 dependency:tree 命令可以帮助分析依赖关系。
拦截器栈配置错误会导致功能异常。比如忘记包含默认拦截器栈,Action 就无法正常接收请求参数。仔细检查拦截器栈的包含关系,确保必要的拦截器都被正确配置。
视图解析失败另一个常见问题。可能是结果类型配置错误,或者视图文件路径不正确。Struts2 支持多种结果类型,比如 dispatcher、redirect、stream 等,需要根据实际需求选择合适的结果类型。
配置文件加载顺序有时也会带来问题。Struts2 支持多个配置文件,加载顺序会影响配置的优先级。理解配置文件的加载机制,能够帮助定位一些看似随机的配置问题。
这些问题的解决往往需要结合日志分析。开启 Struts2 的调试日志,能够清楚地看到框架内部的处理过程,对排查问题非常有帮助。