47

我用 Eclipse Tomcat 编写了一个 Web 应用程序,它可以在我的本地 Tomcat 7 上运行,当我尝试在 Tomcat 7 上在线发布它时,出现以下错误:

严重:servlet [obliquid.servlet.Index] 在路径 [/cp] 的上下文中的 Servlet.service() 引发异常 [绝对 uri:http://java.sun.com/jsp/jstl/core无法在 web.xml 或使用此应用程序部署的 jar 文件中解析]

Tomcat 7 有“规范版本:Servlet 3.0、JSP 2.2、EL 2.2”,所以不包括 JSTL?

当我尝试上传 standard.jar 和 jstl.jar 时,出现以下错误:

org.apache.jasper.JasperException: /jsp/index.jsp (line: 3, column: 62) Unable to read TLD "META-INF/c.tld" from JAR file "jndi:/localhost/cp/WEB-INF /lib/standard.jar”:org.apache.jasper.JasperException:无法加载或实例化 TagLibraryValidator 类:org.apache.taglibs.standard.tlv.JstlCoreTLV

我做了一些谷歌搜索,但我无法解决,有人说这可能是由于罐子的版本冲突引起的。也许我不应该包含这些 jar 并使用不同的 JSTL url?我的是 JSTL 1.1 我想,有没有 JSTL 1.2 的新 URL?

我应该怎么做才能解决问题并使该应用程序运行?

4

9 回答 9

55

我已经为此奋斗了几个小时。这是一个完整的解决方案。

  1. 我正在使用 Tomcat 7,它是一个符合 Servlet 3.0 的服务器。

  2. 如果您希望使用 Servlet 3.0 规范,您的 web.xml 必须如下:

    <web-app 
      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_3_0.xsd" version="3.0"> 
    
  3. 如果你使用 Maven,你的 pom.xml 应该有这些行。

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>jstl-impl</artifactId>
        <version>1.2</version>
        <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 2.1 + Tomcat 7 + Servlet 3.0 非常损坏,除非您使用这些行来修复它,尤其是排除部分。发生的事情是 JSTL 2.1 Jars 实际上引入了错误版本的 Servlet 规范--2.5。除非你阻止这种情况发生,否则你将陷入痛苦的整个世界。特别感谢Murray Todd Williams 先生的这些见解

  4. 最后,如果 Maven 找不到这些 JARS,您可以通过在您的项目中包含三个 JARS 并执行通常的 Project--> Properties--> Java Build Path 并以这种方式包含它们来让 Eclipse 满意——尽管 Maven 应该采取照顾它。

    javax.servlet-api-3.0.1.jar
    javax.servlet.jsp.jstl-1.2.1.jar
    javax.servlet.jsp.jstl-api-1.2.1.jar
    
  5. 请注意!仅当您使用以下神奇组合时,此确切配置才适用:

    1. 符合 Servlet 3.0 的应用程序服务器,例如 Tomcat 7

    2. 您的 web.xml 具有适用于 Servlet 3.0 规范的正确命名空间

    3. 您的类路径上有这三个 JARS,但没有其他 JSTL 或 Servlet JARS。

  6. 确保不要将这些 JAR 的副本放在 WEB-INF/lib 目录中,因为在这种情况下它们会被发送到服务器,从而导致 LinkageErrors。

  7. 在您的 JSP 中,您需要有这条 PRECISE 行,其格式与我的格式完全相同,否则 Eclipse 会抱怨它无法识别 c:blah 标签:

    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
  8. 多么危险的皮塔!这比任何其他版本的 JSTL 都更难实现。这是在以后的迭代中变得更复杂而不是更简单的唯一示例。

于 2012-05-20T14:01:27.723 回答
45

Tomcat 从未包含过 JSTL。

您应该将 jstl 和标准 jars 放入WEB-INF/lib(您已经这样做了),并确保您具有读取它们的权限(chmod)

您的 URI 是正确的,它应该可以工作(在这里工作)

于 2011-05-23T08:23:47.833 回答
14

您的 uri 对于 JSTL 1.2 是正确的。你需要做两件事:

更改您web.xml以使用最新的网络应用程序版本。

它应该看起来像这样或更高版本;

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    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_3_0.xsd" 
    version="3.0">

其次,将正确版本的 jstl jar 放入您的代码中。对于 1.2,您可以在此处下载它们。

这应该给你两个罐子:

  • jstl-api.jar
  • jstl-impl.jar

使用这些,而不是standard.jar以前jstl.jar版本的。

让我们知道这对您有何帮助。

于 2011-09-14T09:54:16.537 回答
8

对于在 apache tomcat 7 上运行,将这些添加到您的 POM 中可能是合适的。这些 jar 不像 glassfish 那样引用 javax.servlet jar,因此不需要排除。

<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-spec</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>1.2.1</version>
</dependency>
于 2014-07-23T17:40:52.357 回答
0

对于 Tomcat,JSTL 1.1.2 有一个更简单的依赖解决方案:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <!-- Apache Taglibs does not implement version 1.2 -->
    <version>1.1.2</version>
  </dependency>
  <dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
    </dependency>
  <dependency>
    <groupId>taglibs</groupId>
    <artifactId>c</artifactId>
    <version>1.1.2</version>
    <type>tld</type>
  </dependency>
  <dependency>
    <groupId>taglibs</groupId>
    <artifactId>fmt</artifactId>
    <version>1.1.2</version>
    <type>tld</type>
  </dependency>
<dependency>

有关详细信息,请参见此处(个人博客)。

REM:根据要求提供更多详细信息,必须包含 JSTL 依赖项才能使它们在 Tomcat 上可用。然而,1.2 版并不是必需的,因为 1.1.2 版(由 Apache 提供,如 Tomcat)也可以完成这项工作。它唯一的要求是Servlet 2.4和JSP 2.2,并且OP提到了Servlet 3.0和JSP 2.0,这已经足够了。

于 2012-07-28T21:43:58.927 回答
0

关于如何在使用 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:

于 2013-09-20T14:21:08.537 回答
0

这些都不适合我,我只是创建了项目而不使用 Maven 并直接添加 JAR 文件。

于 2015-12-16T19:18:25.990 回答
-1

我遇到了错误:严重:Servlet.service() for servlet [obliquid.servlet.Index] in context with path [/cp] throw exception [The absolute uri: http://java.sun.com/jsp/jstl /core无法在 Tomcat 7 上的 web.xml 或随此应用程序部署的 jar 文件中解析]

解决方案:将 jars jstl-1.2.jar 和 javax.servlet.jsp.jstl-api-1.2.1.jar 直接复制到 Tomcat 库目录。再次在 Eclipse 中重新部署 Tomcat 库。

于 2013-05-10T11:53:21.687 回答
-1

pom.xml 中的以下依赖项似乎可以解决该问题:

<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.servlet.jsp.jstl</artifactId>
    <version>1.2.1</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
    <scope>provided</scope>
</dependency>

这是一个奇怪的组合 - 两个不同的 groupIds - 但它确实有效:)。我的期望是看到两个 jar 的相同组 ID。我设法毫无问题地重新部署到 Tomcat 7。

此外,如果您看到“未知标签

于 2013-06-07T06:23:18.780 回答