JSON从JS传递到Java遇阻:Tomcat版本升级引发的Struts2问题
解决Struts2应用在Tomcat 8.0.50中传递JSON参数的问题
这个问题我之前帮朋友排查过类似的,大概率是Tomcat版本升级带来的URL特殊字符解析规则变更导致的——毕竟你从8.0.23跳到8.0.50,中间刚好跨了Tomcat收紧URL字符限制的关键版本(8.0.30),你的jsonparams参数里的{、}、:这些字符,在旧版本Tomcat里能正常解析,新版本直接就拦截了。
下面给你几个可行的解决思路,按推荐程度排序:
1. 改用POST请求传递JSON(最推荐)
GET请求本来就不适合传递复杂的JSON数据,不仅容易触发URL长度限制,还会踩这类字符解析的坑。改成POST的话,把JSON放在请求体里就没这些烦恼了:
- 前端:用
fetch或者axios发送POST请求,把jsonparams的内容放到请求body里,记得设置Content-Type: application/json - 后端:如果是Struts2 2.5+版本,可以直接用
@RequestBody注解解析JSON;旧版本的话,就通过HttpServletRequest获取请求体内容再手动解析成JSON对象。
这种方式完全符合HTTP规范,从根源上避免了URL解析的问题,还更安全。
2. 调整Tomcat的URL解析配置
如果必须保留GET请求的方式,那就修改Tomcat的配置来放宽字符限制:
- 打开
conf/catalina.properties文件,添加或修改以下配置:
# 允许编码后的特殊字符被解析 org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true # 允许URL中包含{}[]这些字符 org.apache.tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}[]
- 或者在
conf/server.xml的<Connector>标签里添加relaxedQueryChars属性,明确指定允许的特殊字符:
<Connector port="10080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" relaxedQueryChars="{}[]:,\""/>
修改完记得重启Tomcat,应该就能正常解析原来的URL了。不过要注意:这种方式会降低URL的安全性,对外服务的话要谨慎使用。
3. 调整Struts2的参数处理配置
最后可以检查下Struts2的struts.xml配置,确保相关参数解析的开关是开启的:
<!-- 允许Action路径中包含斜杠(如果你的URL有这类情况) --> <constant name="struts.enable.SlashesInActionNames" value="true"/> <!-- 允许参数值包含特殊字符 --> <constant name="struts.allowStaticMethodAccess" value="true"/>
不过这个配置的优先级低于Tomcat的设置,如果是Tomcat层面直接拦截了请求,这个可能起不到作用,所以还是优先调整Tomcat的配置。
最后提一句:如果你的Struts2版本比较旧,建议顺便检查下有没有安全补丁要更,避免版本兼容带来其他异常。
内容的提问来源于stack exchange,提问作者m. mann
相关产品推荐
相关产品推荐

