Struts从2.3.35升级到2.5.22后OGNL表达式解析异常问题
从你的描述来看,这个问题的核心是Struts 2.5版本对OGNL表达式解析的安全限制发生了变化,导致你在动作配置中使用的${rollno}无法像2.3.x版本那样自动解析为URL传入的参数值。下面给你两种可行的解决方案,以及问题背后的原因:
方案一:移除冗余的参数配置(推荐)
其实你完全不需要在studentDetail动作的配置中手动添加<param name="rollno">${rollno}</param>这一行。Struts 2的ParametersInterceptor会自动将请求URL中的参数(比如你传入的rollno=5)注入到动作类的同名属性中,只要你的StudentDetailAction满足两个条件:
- 拥有私有属性
private String rollno;(或对应类型,比如Integer) - 提供对应的
setRollno()和getRollno()方法
移除这行配置后,拦截器就能正常获取到URL传入的真实rollno值,这也是Struts 2推荐的参数注入方式,同时避免了OGNL表达式带来的安全风险。
方案二:开启参数中的OGNL表达式解析(不推荐,有安全风险)
如果你因为某些原因必须保留配置中的OGNL表达式,可以在struts.xml中添加以下常量配置,显式允许在动作参数中解析OGNL:
<constant name="struts.ognl.allowExpressionInParams" value="true"/>
⚠️ 注意:这个配置会降低应用的安全性,因为恶意攻击者可能构造包含有害OGNL表达式的请求参数,从而执行未授权的代码。除非你有非常明确的需求,否则强烈建议使用方案一。
额外检查点
- 确认你的自定义拦截器栈
abcStack中包含了ParametersInterceptor(通常通过引用默认栈defaultStack或者直接添加<interceptor-ref name="params"/>),如果缺少这个拦截器,参数注入根本不会生效。 - 检查
StudentDetailAction中的rollno属性类型是否与URL参数的类型匹配(比如URL传的是数字,动作属性用Integer而非String,避免类型转换问题)。
问题根源
Struts 2.5版本为了修复OGNL表达式注入的安全漏洞,默认禁用了在动作配置的<param>标签中解析OGNL表达式。而Struts 2.3.x版本中这个功能是默认开启的,所以你的旧配置在升级后就失效了。官方迁移文档可能没有强调这个细节,导致你遇到了这个异常。
内容的提问来源于stack exchange,提问作者Dixit Jain

