17

我正在开发一个 servlet,它接收包含多个文件内容的多部分请求,并且我正在使用 apache commons 文件上传库。

当我调用parseRequest(request);方法 servlet 时抛出以下异常:

GRAVE: Servlet.service() for servlet DiffOntology threw exception
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
    at org.apache.commons.fileupload.servlet.ServletRequestContext.getContentType(ServletRequestContext.java:73)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:882)
    at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:349)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
    at DiffOntology.doPost(DiffOntology.java:38)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)

我把所有的库都放在了 WEB-INF/lib 中。

编辑:

servlet-api.jar 位于正确的目录(tomcat/lib)中,所有其他库位于 WEB-INF/lib 中

我认为问题可能出在以下几点:我正在 Eclipse 中开发这个 Web 项目,并且我在类路径中导入了文件上传库。

怎么行不通?

我很绝望!!

4

5 回答 5

14

当您将特定于服务器的库放置在 webapp/WEB-INF/lib或可能的JRE/lib. 您将Tomcat复制/lib/servlet-api.jar到那里的机会很大。你不应该那样做。这只会导致类路径中的冲突,从而导致此类错误,并且会使您的 webapp 不可移植(即它只能在 Tomcat 上运行,您不能在 Glassfish、JBoss AS、Websphere 等其他服务器上运行它, ETC)。您应该将特定于服务器的库保留在其默认位置。/WEB-INF/lib从任何特定于服务器的库中清理并从JRE/lib任何 3rd 方库中清理。

您可能在那里复制了特定于服务器的库,因为您无法编译您的 servlet。复制库/WEB-INF/lib是错误的解决方案。您基本上应该只在编译时类路径中指定这些库。由于您使用的是 Eclipse,因此可以轻松完成:首先在Servers视图中添加 Tomcat,然后将您的 webapp 项目与集成的 Tomcat 实例相关联。这样 Eclipse 将自动将特定于服务器的库添加到项目的构建路径中。在全新的 Web 项目上,您可以在项目创建向导期间选择服务器。在现有的 Web 项目上,您可以在项目属性的Targeted Runtimes部分中对其进行修改。

也可以看看:

于 2010-05-23T16:27:21.233 回答
8

您必须将 commons-fileupload.jar 错误地复制到JRE/lib/extJRE/lib/endorsed或以其他方式将其放置在对 servlet API 不可见的类路径中。用 启动 JVM -verbose:class,它将打印哪个类路径加载了ServletFileUpload该类。如果该类是从 以外的任何地方加载的WEB-INF/lib,则需要将其删除。

于 2010-05-23T16:48:02.853 回答
1

旧线程但仍然可以帮助某人。我看到我在测试范围中包含的依赖项中有一个 javax-servlet jar。我做到了提供的范围。如果您使用的是 Eclipse +Maven,请检查依赖关系图。

于 2017-12-20T21:29:15.843 回答
1

当我错误地将 Tomcat 10 Docker 映像用于为 Tomcat 9 构建的 WAR 文件时,我遇到了该错误。我使用了一个没有特定标记的 Docker 映像,该映像随最新的 Tomcat(在我的情况下为 10)(tomcat:jdk17-temurin)。

正如Tomcat 10 文档所述,使用 Tomcat 10 需要进行调整:

Tomcat 9.0.x 和 Tomcat 10.0.x 之间有一个重大的突破性变化。规范 API 使用的 Java 包已从 javax... 更改为 jakarta.... 有必要针对新的 API 重新编译 Web 应用程序。

就我而言,我只是通过指定具有特定 Tomcat 版本(例如tomcat:9.0.56-jdk17-temurin)的图像来解决该错误。

于 2022-01-18T18:29:51.690 回答
0

从 JRE/lib 或 JRE/lib/ext 中删除任何 servlet-api.jar 或上传帮助 jar commons 。这帮助我解决了这个问题。

于 2017-01-23T08:13:09.953 回答