简体   繁体   English

Springboot 应用程序中的 javax.servlet

[英]javax.servlet in Springboot Application

I have a SpringBoot application.我有一个 SpringBoot 应用程序。 One class needs to import javax.servlet.filter and implements the filter for customization.一个类需要导入 javax.servlet.filter 并实现过滤器进行自定义。 It builds successfully locally, but failed to start up on the cloud server and throws llegalStateExceptions.它在本地构建成功,但在云服务器上启动失败并抛出 llegalStateExceptions。 It's the filter class caused the issue.这是过滤器类导致的问题。 Once I remove the filter, the app runs successfully locally and on the cloud.删除过滤器后,该应用程序将在本地和云端成功运行。

I think it might be possible that app could not find javax.servlet api in maven, or it's a servlet/embedded tomcat incompatibility issue.我认为可能是应用程序在 maven 中找不到 javax.servlet api,或者是 servlet/嵌入式 tomcat 不兼容问题。 We have most of the dependencies from org.springframework.boot.我们拥有来自 org.springframework.boot 的大部分依赖项。 The only tomcat related part we have is:我们唯一与 tomcat 相关的部分是:

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

We don't have the following:我们没有以下内容:

<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>

I tried to add them (individually and both) and changed scope to compile, or remove scope.我尝试添加它们(单独和同时添加)并更改范围以进行编译或删除范围。 All sorts of dependencies minor changes, but nothing works so far.各种依赖项都有细微的变化,但到目前为止没有任何效果。 Please let me know if you have any good suggestions.如果您有任何好的建议,请告诉我。

The provided scope means that you intend that library to be provided by the environment in which you deploy your code. provided范围意味着您希望该库由您部署代码的环境提供。 Why would you do such a thing?你为什么要做这样的事情? Well, by default tomcat puts libs containing javax.servlet classes on the classpath for you, and many other servers do the same.嗯,默认情况下 tomcat 将包含 javax.servlet 类的库放在类路径上,许多其他服务器也这样做。 It's a way of allowing container providers (tomcat, jboss, websphere, etc.) to provide custom implementations of a library that specific to their container.这是一种允许容器提供者(tomcat、jboss、websphere 等)提供特定于其容器的库的自定义实现的方法。

Maven interprets the provided scope as meaning that you do not want to include the library in any bundles or deployments, uberjars, zips, or whatever. Maven 将provided范围解释为您不希望将库包含在任何包或部署、uberjars、zip 或其他任何东西中。 Spring-boot produces an uber-jar -- that is, it packages all your application dependencies in your application's single artefact (as opposed to keeping them in separate files which is how we used to do java in the ancient past before we knew better). Spring-boot 生成一个 uber-jar——也就是说,它将所有应用程序依赖项打包在应用程序的单个人工制品中(而不是将它们保存在单独的文件中,这就是我们在我们知道更好之前在古代过去用来做 java 的方式) .

So, if you find that you're missing that package at run time it may be because it isn't actually provided by your container and you have to supply it yourself by removing the scope tag completely.因此,如果您发现在运行时丢失了该包,那可能是因为它实际上不是由您的容器provided的,您必须通过完全删除范围标记来自己提供它。 This will tell maven to bundle it up in your uber-jar for use at runtime.这将告诉 maven 将它捆绑在您的 uber-jar 中以在运行时使用。

Looking at your specific problem, neither of those libraries should be provided so you should remove the scope tags completely from all your dependencies.查看您的具体问题,不应provided这些库中的任何一个,因此您应该从所有依赖项中完全删除范围标记。 If that doesn't work, you have other problems.如果这不起作用,您还有其他问题。

BTW: As an aside, it's a really bad idea to use LATEST as the version number for any dependency.顺便说一句,使用LATEST作为任何依赖项的版本号是一个非常糟糕的主意。 It violates dozens of best-practices and against certain binary stores (nexus for example) it barely works and isn't guaranteed.它违反了许多最佳实践,并且针对某些二进制存储(例如,nexus),它几乎不起作用并且无法保证。 You should instead find out which version of tomcat-jdbc you're meant to be using and use the absolute version instead.相反,您应该找出您打算使用的 tomcat-jdbc 版本,并改用绝对版本。 In this case the LATEST version is almost certainly the wrong one to be using.在这种情况下, LATEST版本几乎肯定是错误的。

I had meet problem like this by using Gradle in SpringBoot application, finally I found it question is lost of javax.servlet-api, root cause is that it's scope is not correct, when it's scope is provided ,IDEA won't build complete, so servlet-api Jar file not contain in build file.我在 SpringBoot 应用程序中使用 Gradle 遇到了这样的问题,最后我发现它的问题是 javax.servlet-api 丢失了,根本原因是它的范围不正确,当它的范围被provided ,IDEA 不会构建完整,所以 servlet-api Jar 文件不包含在构建文件中。 After change scope from provided to runtime , it fixed.将范围从provided更改为runtime ,它修复了。 You can reference this blog http://blog.csdn.net/u013360850/article/details/71520210你可以参考这个博客http://blog.csdn.net/u013360850/article/details/71520210

Just Run The Project If You have Runtime provided in your Gradle build (If you are using gradle) It Might automatically solve your issue.如果您的 Gradle 构建中提供了运行时,则只需运行该项目(如果您使用的是 gradle)它可能会自动解决您的问题。 Done the same in my case在我的情况下做同样的事情

The problem with spring-boot is there sometimes the jars are provided multiple times due to many uber jars, so to resolve the problem as there is already embedded Tomcat we could simply add: 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> 

and not both as you tried.而不是你尝试过的两者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM