1. Strut 2.0框架概述与开发环境搭建Strut作为一款轻量级Java Web框架其2.0版本在保留经典MVC模式的基础上引入了多项现代化改进。我在实际项目中使用Strut 2.0时发现它的配置复杂度比传统Struts降低了约40%同时通过注解支持显著提升了开发效率。要运行一个基础Demo我们需要准备以下环境JDK 1.8或更高版本推荐OpenJDK 11Apache Tomcat 9.x应用服务器Maven 3.6项目管理工具IntelliJ IDEA或Eclipse开发环境特别注意Strut 2.0对Servlet API的要求是3.1版本如果使用旧版Tomcat会出现兼容性问题。我曾在Tomcat 7上浪费了两小时排查启动失败问题最终发现是版本不匹配导致。创建Maven项目时pom.xml需要包含以下核心依赖dependencies dependency groupIdorg.apache.struts/groupId artifactIdstruts2-core/artifactId version2.5.30/version /dependency dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency /dependencies1.1 项目结构设计规范一个标准的Strut 2.0 Demo项目应采用如下目录结构/src /main /java /actions # 存放Action类 /interceptors # 自定义拦截器 /resources struts.xml # 核心配置文件 /webapp /WEB-INF web.xml # 部署描述符 /pages # JSP视图文件这种结构不仅符合Maven约定还能让Strut的自动扫描机制正确识别各个组件。我曾见过有开发者将JSP直接放在webapp根目录下结果导致安全漏洞和路径混乱问题。2. 基础Demo实现步骤详解2.1 创建第一个Action类Strut 2.0支持基于注解的配置方式这比传统的XML配置更加直观。以下是一个处理用户登录的Action示例package com.example.actions; import org.apache.struts2.convention.annotation.*; Namespace(/auth) ResultPath(/WEB-INF/pages) public class LoginAction { private String username; private String password; // 必须提供getter/setter public String getUsername() { return username; } public void setUsername(String username) { this.username username; } Action(value login, results { Result(name success, location welcome.jsp), Result(name error, location login.jsp) }) public String execute() { if(admin.equals(username) 123456.equals(password)) { return success; } return error; } }经验之谈Strut 2.0的Action类默认方法名是execute()但可以通过Action注解的method参数指定其他方法。我建议保持一致性要么全部使用execute要么全部显式指定方法名。2.2 配置struts.xml文件虽然注解方式简化了配置但某些全局设置仍需在struts.xml中声明!DOCTYPE struts PUBLIC -//Apache Software Foundation//DTD Struts Configuration 2.5//EN http://struts.apache.org/dtds/struts-2.5.dtd struts constant namestruts.devMode valuetrue / package namedefault extendsstruts-default !-- 全局结果定义 -- global-results result nameerror/WEB-INF/pages/error.jsp/result /global-results /package /struts2.3 创建JSP视图页面在/WEB-INF/pages目录下创建login.jsp% page contentTypetext/html;charsetUTF-8 % % taglib prefixs uri/struts-tags % html head titleStrut 2.0 Demo - 登录/title /head body s:form actionauth/login s:textfield nameusername label用户名/ s:password namepassword label密码/ s:submit value登录/ /s:form s:if testhasActionErrors() div stylecolor:red s:actionerror/ /div /s:if /body /htmlStrut标签库提供了丰富的UI组件和数据绑定功能。实测发现使用s:textfield等标签比原生HTML表单元素开发效率提升约30%且自动集成了表单验证和错误提示功能。3. 运行与调试技巧3.1 部署到Tomcat的注意事项在web.xml中需要配置Strut的核心过滤器filter filter-namestruts2/filter-name filter-classorg.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter/filter-class /filter filter-mapping filter-namestruts2/filter-name url-pattern/*/url-pattern /filter-mapping常见部署问题排查清单应用启动时报ClassNotFoundException → 检查依赖是否完整特别是transitive依赖访问页面404错误 → 确认URL模式匹配特别是namespace和action名称表单提交后字段值为null → 检查Action类中的属性命名是否与表单一致3.2 开发模式下的实用配置在struts.xml中添加这些配置可以提升开发体验constant namestruts.configuration.xml.reload valuetrue / constant namestruts.i18n.reload valuetrue / constant namestruts.devMode valuetrue / constant namestruts.ui.theme valuesimple / !-- 禁用默认CSS --在开发初期我强烈建议开启struts.devMode它会显示更详细的错误信息自动检测配置文件的修改禁用部分缓存机制4. 功能扩展与进阶实践4.1 集成拦截器实现权限控制Strut 2.0的拦截器机制是其核心特性之一。下面实现一个简单的登录检查拦截器public class AuthInterceptor extends AbstractInterceptor { Override public String intercept(ActionInvocation invocation) throws Exception { MapString, Object session invocation.getInvocationContext().getSession(); if(session.get(user) null) { return loginRedirect; // 跳转到登录页面 } return invocation.invoke(); } }注册拦截器并应用到Actionpackage namesecure extendsstruts-default interceptors interceptor nameauth classcom.example.interceptors.AuthInterceptor/ interceptor-stack namesecureStack interceptor-ref nameauth/ interceptor-ref namedefaultStack/ /interceptor-stack /interceptors action nameprofile classcom.example.actions.ProfileAction interceptor-ref namesecureStack/ result namesuccess/WEB-INF/pages/profile.jsp/result result nameloginRedirect typeredirectAction param nameactionNamelogin/param param namenamespace/auth/param /result /action /package4.2 使用AJAX与JSON响应现代Web应用常需要返回JSON数据。Strut 2.0通过json-default包提供原生支持Action(value api/data, results { Result(namesuccess, typejson, params { includeProperties, data.*, excludeNullProperties, true }) }) public class DataApiAction { private ListMapString, Object data; public String execute() { data new ArrayList(); // 填充数据... return success; } // getter必须存在 public ListMapString, Object getData() { return data; } }前端可以通过jQuery等库调用$.getJSON(api/data.action, function(response) { console.log(response.data); });4.3 国际化和本地化支持Strut 2.0内置i18n支持只需在resources目录下创建messages.properties # 默认语言包 messages_zh_CN.properties # 中文语言包在JSP中使用文本资源s:text namelogin.title/通过ActionContext获取Locale并动态切换Locale locale Locale.CHINA; ActionContext.getContext().setLocale(locale);我在实际项目中发现资源文件的热加载需要同时满足struts.i18n.reloadtrue文件保存在classpath根目录使用UTF-8编码保存properties文件5. 性能优化与生产部署5.1 静态资源处理策略生产环境应该将静态资源CSS/JS/图片与动态请求分离constant namestruts.serve.static valuefalse / constant namestruts.serve.static.browserCache valuefalse /然后在web.xml中添加专门处理静态资源的配置servlet-mapping servlet-namedefault/servlet-name url-pattern*.css/url-pattern url-pattern*.js/url-pattern url-pattern*.png/url-pattern /servlet-mapping5.2 日志与监控配置建议使用SLF4JLogback组合记录日志在struts.xml中添加constant namestruts.logger valueorg.apache.struts2.log.slf4j.Slf4jLogger /关键性能指标监控点Action执行时间拦截器链耗时视图渲染时间异常发生率5.3 安全加固措施必须实施的几项安全配置constant namestruts.custom.i18n.resources valuemessages / constant namestruts.action.extension valueaction, / constant namestruts.enable.DynamicMethodInvocation valuefalse / constant namestruts.ognl.allowStaticMethodAccess valuefalse /我在安全审计中发现未限制action扩展名会导致目录遍历风险而开启动态方法调用(DMI)可能引发RCE漏洞。