Spring Boot 4嵌入式Tomcat(11.0.15版本)无法引用嵌套枚举类
在迁移到Spring Boot 4(Spring Boot 3.5)之前,通过嵌入式Tomcat服务器运行时,Web应用可以像下面这样在JSP中引用嵌套的枚举类:
Java类包含一个嵌套枚举:
package application.domain;
@Entity
public class Form {
public enum Type {
STANDARD("Standard"),
ADVANCED("Advanced");
private final String label;
Type(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
@Id
@GeneratedValue
private Long id;
private String title;
//....
}
JSP视图:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page import="application.domain.Form.Type" %>
<select name="type" class="form-control">
<c:forEach var="type" items="${Type.values()}">
<option value='${type}' ${form.type== type ? 'selected' : ''}>${type.label}</option>
</c:forEach>
</select>
但在Spring Boot 4.0.2(Tomcat 11.0.15)时,${Type.values()} 的结果现在是空白(没有抛出错误也没有显示,只有没有被解析)。
在Spring Boot 3.5到 4(或很可能是Tomcat 10.1.x到 11.x)之间发生了什么变动,导致这个解析不再起作用?除了将嵌套的枚举类重构为顶级类之外,还有没有其他变通办法?
我需要指出的是,当把Spring Boot应用作为WAR文件部署到独立的Tomcat 11服务器上时,这个是可行的(与嵌入式环境相对)。
JSP EL访问像这样嵌套类的能力自Tomcat 10.1.41+起就一直可用(参见 https://bz.apache.org/bugzilla/show_bug.cgi?id=69635 和 https://github.com/jakartaee/expression-language/issues/313)
解决方案
这不是Spring Boot或 Tomcat的问题,而是嵌入式容器中的类路径扁平化问题(与传统的独立WAR部署相比)。
当在同一个扁平类路径上混合容器实现和API JAR时(嵌入式容器会这样做),你可能会遇到排序相关的问题,就像我遇到的那样。这并不是一个bug,因为规范假设容器的类加载器是分离的。
为缓解该问题,请指定正确的依赖顺序(即先jasper,再JSTL):
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>11.0.15</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
</dependency>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。