维护老 SSM/SSH 项目常遇到——web.xml 里 version="2.5",跑起来应该配哪个 Tomcat?JDK 8 能跑吗?先给对照表:
Servlet 与 Tomcat 版本对照
| Servlet 版本 | Tomcat 版本 | 官方支持 JDK |
|---|---|---|
| Servlet 2.4 | Tomcat 5.0/5.5 | Java 1.4 / 5 |
| Servlet 2.5 | Tomcat 6.x | Java 5 / 6 |
| Servlet 3.0 | Tomcat 7.x | Java 6 / 7 |
| Servlet 3.1 | Tomcat 8.0 | Java 7 / 8 |
| Servlet 3.1 | Tomcat 8.5 | Java 7 / 8 |
| Servlet 4.0 | Tomcat 9.x | Java 8+ |
| Jakarta Servlet 5 | Tomcat 10.x | Java 8+ |
| Jakarta Servlet 6 | Tomcat 11.x | Java 17+ |
Tomcat 10 是分水岭——包名从 javax.servlet.* 改到 jakarta.servlet.*。老代码原封不动放 Tomcat 10 直接编译不过。
判断项目该用哪个
打开 web.xml,看头部:
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
</web-app>
version="2.5" 就是 Servlet 2.5,对应 Tomcat 6+。
JDK 8 能跑 Servlet 2.5 项目吗
能。稳定组合:
| 项 | 推荐 |
|---|---|
| Servlet 规范 | 2.5(保持 web.xml 不变) |
| Tomcat | 7.0.109(最后一个 7.x) |
| JDK | 1.8 |
| Spring | 3.x / 4.x |
| MyBatis | 3.x |
理由:
- Tomcat 7 向下兼容 Servlet 2.5(Tomcat 是超集)
- Tomcat 7 完整支持 JDK 8,无 PermGen 问题
- Tomcat 6 对 JDK 8 支持不完整,从 6.0.53 才勉强能跑,还是别用了
迁移 Tomcat 6 到 Tomcat 7 要改什么
九成情况什么都不用改。真要改的坑:
1. web.xml schema 版本:可以不动。Tomcat 7 依然接受 web-app version="2.5"。
2. JSP 的 EL 表达式:Tomcat 7 默认 EL 2.2、Tomcat 6 是 EL 2.1。有些字符串比较写法(比如 ${x eq null})在两版本略有差异,一般不影响。
3. 端口 / 编码:server.xml 里 Connector 改:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
URIEncoding="UTF-8" 治所有 GET 参数中文乱码。
4. session:Tomcat 7 默认关闭了 sessionId URL 追加(;jsessionid=xxx)。老 JSP 依赖 <c:url> 处理会不同,一般不影响。
Maven 里跑 Tomcat:tomcat7-maven-plugin
不装 Tomcat 也能跑,用 Maven 插件:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
跑:
mvn tomcat7:run
这个插件已经没维护 10 多年了,但对 Servlet 2.5 老项目照样能跑。生产别用,本地开发够。
Tomcat 8/9 呢
Servlet 2.5 项目理论上放 Tomcat 8/9 也能跑(javax.servlet 包名不变)。但会遇到:
- 老 Spring 3.x 和 Tomcat 8 的 WebSocket 冲突
- 一些 EL 2.2 / 3.0 的表达式行为差异
- JSP 编译器更严格
迁移建议:如果项目还在开发新功能,直接升到 Tomcat 9 + JDK 8 + Servlet 3.x(web.xml 头改一下);只是维护,稳留 Tomcat 7 + JDK 8。
Tomcat 10+ 的 jakarta 大坑
老代码:
import javax.servlet.http.HttpServletRequest;
Tomcat 10 只认:
import jakarta.servlet.http.HttpServletRequest;
想迁移,用官方工具批量替换:
# Eclipse Transformer
java -jar org.eclipse.transformer.cli-*.jar \
--input old.war --output new.war
或者手工找替换:
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} +
改完还要处理 Spring 版本——Spring 5.x 只支持 javax.servlet,要 jakarta 得升到 Spring 6.x(同时 JDK 17+)。这是个大工程,不是小改。
一句话总结
老 Servlet 2.5 项目最稳的组合是 Tomcat 7.0.109 + JDK 8。Tomcat 10 起改包名 jakarta,迁移是大工程。开发用 tomcat7-maven-plugin 快。
