IDEA创建Java EE项目,使用Spring + Spring MVC + MyBatis框架,使用maven管理依赖。项目当前的环境是:
- Tomat 10.1.28
- Maven 3.6.3
- JDK 17
项目的功能:读取数据库的report表中的数据,返回一个List集合对象reportList
在JSP页面上,使用EL表达式+JSTL标签库,遍历集合,显示每一条report信息。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body><h3>欢迎登录,${sessionScope.get("user").name}</h3><div><table><c:forEach items="${reportList}" var="report"><tr><td>报告编号:</td><td>${report.id}</td><td>报告名称:</td><td>${report.reportName}</td><td>报告内容:</td><td>${report.reportContext}</td><td>报告截止提交日期:</td><td>${report.deadlineTime}</td></tr></c:forEach></table></div>
</body>
</html>
EL表达式和JSTL标签的使用,需要再项目的pom.xml文件引入了一下依赖
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version>
</dependency><!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
因为还需要使用HttpServletRequest
对象,并且Tomcat版本是Tomcat10.1.28
版本,所以项目的pom.xml增加了jakarta.servlet-api
的依赖
<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.1.0</version><scope>provided</scope>
</dependency>
运行后,出现下面这样的报错:
java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagLibraryValidator
针对错误,去搜索了相关的解决办法,发现javax.servlet.jstl
也不再符合Tomcat10版本的需求,需要使用jakarta.servlet.jsp.jstl-api
版本,所以更改了pom.xml的依赖引用:
<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.1.0</version><scope>provided</scope>
</dependency><!--https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api-->
<dependency><groupId>jakarta.servlet.jsp.jstl</groupId><artifactId>jakarta.servlet.jsp.jstl-api</artifactId><version>3.0.2</version>
</dependency><!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
结果运行还是报同样的错误。
最终在stackoverflow上找到了一篇文章https://stackoverflow.com/questions/8021370/java-lang-noclassdeffounderror-javax-servlet-jsp-tagext-taglibraryvalidator
The javax.servlet.jsp.tagext.TagLibraryValidator class is introduced in JSP 2.0 and then later repackaged to jakarta.servlet.jsp.tagext.TagLibraryValidator in JSP 3.0. This error can thus have the following possible causes:
javax.servlet.jsp.tagext.TagLibraryValidator 类是在 JSP 2.0 中引入的,后来在 JSP 3.0 中重新打包为 jakarta.servlet.jsp.tagext.TagLibraryValidator。因此,此错误可能有以下可能的原因:
- You are not running a JSP 2.0 compatible servletcontainer. For example, Tomcat 4.x or 5.0. You need a Tomcat version between 5.5 and 9.0.
您没有运行与 JSP 2.0 兼容的 servletcontainer。例如,Tomcat 4.x 或 5.0。您需要 5.5 到 9.0 之间的 Tomcat 版本。
- You are actually running a JSP 3.0 compatible servletcontainer (the first version with jakarta package instead of javax) such as Tomcat 10.0 or newer. In that case you’ll need to upgrade JSTL from 1.x to 2.0 or newer. Installation instructions can be found in How to install JSTL? It fails with “The absolute uri cannot be resolved” or “Unable to find taglib” or NoClassDefFoundError or ClassCastException.
您实际上正在运行与 JSP 3.0 兼容的 servletcontainer(第一个使用 jakarta 包而不是 javax 的版本),例如 Tomcat 10.0 或更新版本。在这种情况下,您需要将 JSTL 从 1.x 升级到 2.0 或更新版本.安装说明可以在 How to install JSTL? It fails with “The absolute uri cannot be resolved” or “Unable to find taglib” or NoClassDefFoundError or ClassCastException.
- You have cluttered the /WEB-INF/lib with arbitrarily downloaded jsp-api.jar or j2ee.jar or javaee.jar files or whatever contains the JSP API, which originates from a completely different servletcontainer make/version which in turn was actually not JSP 2.0 compliant. Get rid of those libraries. You don’t need them. If you did this to workaround compilation errors, then you did it the wrong way. They should end up in compiletime classpath, not in the runtime classpath. See also How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
您已将任意下载的 jsp-api.jar 或 j2ee.jar 或 javaee.jar 文件或任何包含 JSP API 的文件弄得乱七八糟,这些文件来自完全不同的 servletcontainer make/version,而后者实际上并不符合 JSP 2.0 标准。删除这些库。您不需要它们。如果您这样做是为了解决编译错误,那么您做错了。它们应该位于编译时类路径中,而不是运行时类路径中。另请参阅How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
在这个回答中,介绍了另一篇文章 How to install JSTL? It fails with “The absolute uri cannot be resolved” or “Unable to find taglib” or NoClassDefFoundError or ClassCastException.
所以在pom.xml文件中又增加了jakarta.servlet.jsp.jstl
的依赖
<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.1.0</version><scope>provided</scope>
</dependency><!--https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api-->
<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><!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
重启项目,页面访问数据显示正常。