【问题标题】:javax.servlet in Springboot ApplicationSpring Boot 应用程序中的 javax.servlet
【发布时间】:2017-12-30 18:46:45
【问题描述】:

我有一个 SpringBoot 应用程序。一个类需要导入 javax.servlet.filter 并实现自定义的过滤器。它在本地构建成功,但在云服务器上启动失败并抛出 llegalStateExceptions。这是导致问题的过滤器类。删除过滤器后,应用程序在本地和云上成功运行。

我认为应用程序可能无法在 maven 中找到 javax.servlet api,或者是 servlet/embedded tomcat 不兼容问题。我们拥有来自 org.springframework.boot 的大部分依赖项。我们唯一与tomcat相关的部分是:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>LATEST</version>
</dependency>

我们没有以下内容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

我尝试添加它们(单独和两者)并更改范围以编译或删除范围。各种依赖项都有细微的变化,但到目前为止没有任何效果。如果您有任何好的建议,请告诉我。

【问题讨论】:

    标签: java maven servlets spring-boot


    【解决方案1】:

    provided 范围意味着您希望该库由您部署代码的环境提供。你为什么要做这样的事?好吧,默认情况下,tomcat 会将包含 javax.servlet 类的库放在类路径中,许多其他服务器也这样做。这是一种允许容器提供者(tomcat、jboss、websphere 等)提供特定于其容器的库的自定义实现的方法。

    Maven 将provided 范围解释为您不希望将库包含在任何捆绑包或部署、uberjar、zip 或其他任何东西中。 Spring-boot 生成一个 uber-jar - 也就是说,它将所有应用程序依赖项打包在应用程序的单个工件中(而不是将它们保存在单独的文件中,这是我们在古代使用 java 的方式,在我们知道更好之前) .

    因此,如果您发现在运行时缺少该包,可能是因为它实际上不是您的容器中的provided,您必须自己通过完全删除范围标记来提供它。这将告诉 maven 将其捆绑在您的 uber-jar 中以在运行时使用。

    查看您的具体问题,这些库都不应该是provided,因此您应该从所有依赖项中完全删除范围标签。如果这不起作用,您还有其他问题。

    顺便说一句:顺便说一句,使用LATEST 作为任何依赖项的版本号是一个非常糟糕的主意。它违反了数十种最佳实践,并且针对某些二进制存储(例如,nexus)几乎无法正常工作并且无法保证。相反,您应该找出您打算使用的 tomcat-jdbc 版本,并改用绝对版本。在这种情况下,LATEST 版本几乎肯定是错误的版本。

    【讨论】:

      【解决方案2】:

      我在SpringBoot应用程序中使用Gradle遇到过这样的问题,最后我发现问题是javax.servlet-api丢失了,根本原因是它的范围不正确,当它的范围是provided时,IDEA赢了'构建不完整,因此 servlet-api Jar 文件不包含在构建文件中。将范围从provided 更改为runtime 后,它已修复。可以参考这篇博客http://blog.csdn.net/u013360850/article/details/71520210

      【讨论】:

        【解决方案3】:

        spring-boot 的问题在于,由于uber jar 很多,有时会多次提供 jar,因此要解决问题,因为已经嵌入了 Tomcat,我们可以简单地添加:

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency> 
        

        而不是像你尝试的那样。

        【讨论】:

          【解决方案4】:

          如果您在 Gradle 构建中提供了运行时,只需运行项目(如果您使用的是 gradle)它可能会自动解决您的问题。在我的情况下也做了同样的事情

          【讨论】:

            猜你喜欢
            • 2017-10-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-19
            • 2023-03-16
            • 2019-08-31
            相关资源
            最近更新 更多