从Java 8迁移到Java 17搭配Spring Boot 3时遇到ESAPI问题
将项目从Java 8迁移至Java 17,并升级Spring Boot到3.0.4版本后,在JWT安全防护的JwtRequestFilter类(继承OncePerRequestFilter)中,调用ESAPI的addHeader方法时出现编译错误:
The type javax.servlet.http.HttpServletResponse cannot be resolved. It is indirectly referenced from required type org.owasp.esapi.ESAPI
原因是Spring Boot 3.x全面切换到Jakarta EE规范,使用jakarta.servlet.http.HttpServletResponse,但旧版本ESAPI依赖的是javax.servlet.http.HttpServletResponse,导致包规范冲突。
1. 升级ESAPI到支持Jakarta EE的版本
ESAPI从2.5.0.0版本开始正式支持Jakarta EE,这是最彻底的解决方式。
Maven依赖配置:
<dependency> <groupId>org.owasp.esapi</groupId> <artifactId>esapi</artifactId> <version>2.5.0.0</version> <!-- 或更高稳定版本 --> </dependency>
Gradle依赖配置:
implementation 'org.owasp.esapi:esapi:2.5.0.0'
升级后,ESAPI的httpUtilities().addHeader方法会适配jakarta.servlet.http.HttpServletResponse,同时需确保代码中所有Servlet相关导入切换为Jakarta包:
// 替换原javax包导入 import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException;
2. 临时兼容方案(不升级ESAPI时)
如果暂时无法升级ESAPI,可添加Jakarta到javax的桥接依赖,让项目同时兼容两种包规范:
Maven添加桥接依赖:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jakartaee-migration</artifactId> <version>1.0.0</version> <scope>provided</scope> </dependency>
同时排除Spring Boot Starter Web中原有的javax.servlet依赖,避免冲突:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </exclusion> </exclusions> </dependency>
注意:此方案仅作为临时过渡,长期建议升级ESAPI到支持Jakarta的版本,避免潜在兼容性问题。
3. 替换ESAPI的Header操作(备选)
若不想依赖ESAPI的addHeader方法,可直接使用Jakarta Servlet原生API添加请求头,绕过包冲突:
// 替换ESAPI调用 response.addHeader(name, value); // 若需安全处理,可自行用ESAPI编码器转义值: // String safeValue = ESAPI.encoder().encodeForHTMLAttribute(value); // response.addHeader(name, safeValue);
内容的提问来源于stack exchange,提问作者siva

