关于如何在使用 Maven 处理此问题时解决此问题,这里有两个答案大部分是正确的。但是,两者都不是 100% 完成的。
根据@Tom Hunter 的回答使用排除项
这个答案有效。但是,仍然会有来自 Tomcat 的有关重复 TLD 定义的日志消息。这是因为 jstl 和 jstl-impl 工件都包含 TLD 定义。要删除这些消息,我认为更好的 Maven 设置是这样的:
<dependency>
<version>1.2</version>
<scope>runtime</scope>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
<exclusion>
<artifactId>jsp-api</artifactId>
<groupId>javax.servlet.jsp</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
<exclusion>
<artifactId>jsp-api</artifactId>
<groupId>javax.servlet.jsp</groupId>
</exclusion>
<exclusion>
<artifactId>jstl-api</artifactId>
<groupId>javax.servlet.jsp.jstl</groupId>
</exclusion>
</exclusions>
</dependency>
这仅包括具有必要排除项的 jstl api 类,以避免在该答案的其余部分中解释的问题。
根据@George的回答使用较新的 POM 版本
我花了一段时间才意识到这一点,但是有更新版本的 JSTL pom 可用。这真的很令人困惑,因为这些较新的包使用相似但略有不同的命名约定。这些较新的版本将 javax.servlet、javax.jsp 等依赖项标记为提供的范围,因此不需要排除它们。1.2.1 版本依赖于 1.2.1 版本的 jstl-api。所以这和上面的答案一样有效:
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.1</version>
<scope>runtime</scope>
</dependency>
这与乔治的回答略有不同,因为我将范围更改为运行时。George 指定了所提供的范围。使用提供的范围,必须将 jar 手动复制到 Tomcat lib 目录中,或者必须包含一些其他依赖项来包含必要的实现。
但是,我在 maven Central、jboss 存储库或任何其他存储库中找不到 impl 的 1.2.1 版本。我最终转了一圈,最后只使用了一个基于本地文件的 repo 来存储 jar。此处描述了依赖项和 jar: