Servlet返回“HTTP状态404请求的资源(/ servlet)不可用”

我在我的WebContent/jsps文件夹的JSP文件中有一个HTML表单。 我在我的src文件夹的默认包中有一个servlet类servlet.java 。 在我的web.xml它被映射为/servlet

我已经尝试了HTML表单的action属性中的几个URL:

 <form action="/servlet"> 
 <form action="/servlet.java"> 
 <form action="/src/servlet.java"> 
 <form action="../servlet.java"> 

但是没有一个工作。 他们都不断地在Tomcat 6/7/8中返回如下的HTTP 404错误:

HTTP状态404 – / servlet

说明 :请求的资源(/ servlet)不可用。

或者如下Tomcat 8.5 / 9:

HTTP状态404 – 未find

消息 :/ servlet

说明 :原始服务器没有find目标资源的当前表示,或者不愿意透露目标资源的存在

为什么它不工作?

把servlet类放在一个package

首先,把这个servlet类放在一个Java package 。 您应该始终在一个包中公开可重用的Java类,否则它们对于包中的类(如服务器本身)是不可见的。 这样可以消除潜在的环境特定问题。 无包servlet只能在特定的Tomcat + JDK组合中工作,不应该依赖这个组合。

对于“普通”IDE项目,该类需要放在“Java Resources”文件夹内的包结构中,因此不是 “WebContent”,这是针对诸如JSP的Web文件。 以下是导航器视图中所示的默认Eclipse dynamicWeb项目的文件夹结构示例:

 EclipseProjectName |-- src | `-- com | `-- example | `-- YourServlet.java |-- WebContent | |-- WEB-INF | | `-- web.xml | `-- jsps | `-- page.jsp : 

在Maven项目的情况下,这个类需要被放在main/java里面的包结构中,因此不需要 main/resources ,这个是非类文件 。 以下是在Eclipse的Navigator视图中看到的默认Maven webapp项目的文件夹结构示例:

 MavenProjectName |-- src | `-- main | |-- java | | `-- com | | `-- example | | `-- YourServlet.java | |-- resources | `-- webapp | |-- WEB-INF | | `-- web.xml | `-- jsps | `-- page.jsp : 

请注意, /jsps子文件夹不是严格必要的。 你甚至可以没有它,并把JSP文件直接放在webcontent / webapp的根,但我只是接pipe你的问题。

url-pattern设置servlet URL

servlet URL被指定为servlet映射的“URL模式”。 绝对不是每个定义的servlet类的类名/文件名。 URL模式将被指定为@WebServlet注释的值。

 package com.example; // Use a package! @WebServlet("/servlet") // This is the URL of the servlet. public class YourServlet extends HttpServlet { // Must be public and extend HttpServlet. // ... } 

如果您想要支持像/servlet/foo/bar这样的path参数,请使用/servlet/*的URL模式。 另请参阅像/ xyz / {value} / test这样的Servlet和path参数,如何在web.xml中映射?

@WebServlet仅适用于Servlet 3.0或更新版本

为了使用@WebServlet ,你只需要确保你的web.xml文件(如果有的话)(Servlet 3.0以后是可选的)被声明为符合Servlet 3.0+版本,因此符合2.5版本或更低的版本 。 下面是一个与Servlet 3.1兼容的(与Tomcat 8+,WildFly 8+,GlassFish 4+等相匹配的)。

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1" > <!-- Config here. --> </web-app> 

或者,如果您不在Servlet 3.0以上(不是Tomcat 7或更新版本,但Tomcat 6或更早版本),则删除@WebServlet注释。

 package com.example; public class YourServlet extends HttpServlet { // ... } 

然后把servlet注册到web.xml如下所示:

 <servlet> <servlet-name>yourServlet</servlet-name> <servlet-class>com.example.YourServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>yourServlet</servlet-name> <url-pattern>/servlet</url-pattern> <!-- This is the URL of the servlet. --> </servlet-mapping> 

请注意,你不应该使用两种方式。 使用基于注释的configuration或基于XML的configuration。 如果两者都有,那么基于XML的configuration将覆盖基于注释的configuration。

validation构build/部署

如果您使用的是Eclipse和/或Maven等构build工具,则需要确保编译的servlet类文件位于生成的WAR文件的/WEB-INF/classes文件夹中的包结构中。 在package com.example; public class YourServlet情况下, package com.example; public class YourServlet ,它必须位于/WEB-INF/classes/com/example/YourServlet.class 。 否则,如果@WebServlet出现404错误,或者<servlet>出现如下的HTTP 500错误,您将面对:

HTTP状态500

实例化servlet类com.example.YourServlet时出错

并在服务器日志中find一个java.lang.ClassNotFoundException: com.example.YourServlet ,接着是一个java.lang.NoClassDefFoundError: com.example.YourServlet ,然后是javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet

validationservlet是否被正确编译并放置在classpath中的简单方法是让构build工具生成WAR文件(例如,右键单击项目,在Eclipse中导出> WAR文件 ),然后使用ZIP工具检查其内容。 如果/WEB-INF/classes缺lessservlet /WEB-INF/classes ,那么项目configuration错误或某些IDE /项目configuration默认值被错误地还原(例如,在Eclipse中已经禁用了Project> Automatically )。 如果你不知道,最好是重新开始,不要碰任何IDE /项目configuration的默认值。

单独testingservlet

如果服务器在localhost:8080上运行,并且WAR已成功部署在/contextname的上下文path中(默认为IDE项目名,区分大小写!),并且该servlet没有失败其初始化(读取服务器logging任何部署/ servlet成功/失败消息以及实际的上下文path和servlet映射),那么可以在http://localhost:8080/contextname/servlet使用URL模式为/servlet http://localhost:8080/contextname/servlet

你可以直接在浏览器的地址栏中input它来不经意间进行testing。 如果它的doGet()被正确覆盖并且被实现,那么你会在浏览器中看到它的输出。 或者,如果你没有任何doGet()或者如果它不正确地调用super.doGet() ,那么将显示“ HTTP 405:HTTP方法GET不被这个URL支持 ”的错误(这仍然比404因为405certificate了servlet本身实际上是被发现的)。

重写service()是一个不好的做法,除非你正在重新创build一个MVC框架 – 如果你刚刚开始使用servlet,并且对当前问题中描述的问题一无所知,这是不太可能的)另请参见Design Patterns web基于应用程序

无论如何,如果servlet在被testing的时候已经返回了404,那么用一个HTML表单来完全没有意义。 从逻辑上来说,将任何HTML表单包含在有关来自servlet的404错误的问题中也是毫无意义的。

从HTML引用servlet URL

一旦你确认servlet在单独调用的时候工作的很好,那么你可以前进到HTML。 至于你的HTML表单的具体问题, <form action>值需要是一个有效的URL。 这同样适用于<a href> 。 您需要了解绝对/相对URL的工作方式。 您知道,url是url,您可以在网页浏览器的地址栏中input/查看。 如果您将相对URL指定为表单操作(即没有http://scheme),那么它就相对于当前url,就像您在浏览器的地址栏中看到的那样。 因此,绝对不是与服务器的WAR文件夹结构中的JSP / HTML文件位置相关的,因为许多初学者似乎认为。

因此,假定带有HTML表单的JSP页面是通过http://localhost:8080/contextname/jsps/page.jsp打开的,并且您需要提交到位于http://localhost:8080/contextname/servlet ,这里有几种情况(请注意,您可以用<a href> here)安全地replace<form action>

  • 表单操作提交到带有斜杠的URL。

     <form action="/servlet"> 

    引导斜杠/使URL相对于域,因此表单将提交到

     http://localhost:8080/servlet 

    但是这可能会导致一个404错误的情况。


  • 表单操作提交给一个没有前导斜杠的URL。

     <form action="servlet"> 

    这使URL相对于当前URL的当前文件夹,从而表单将提交到

     http://localhost:8080/contextname/jsps/servlet 

    但这可能会导致一个404,因为它在错误的文件夹中。


  • 表单操作提交到一个文件夹上的URL。

     <form action="../servlet"> 

    这将把一个文件夹(就像在本地磁盘文件系统path!),这样的forms将提交到

     http://localhost:8080/contextname/servlet 

    这个必须工作!


  • 但是,规范的方法是使URL相对于URL成为域名,以便在将JSP文件移动到另一个文件夹时,不需要再次修复URL。

     <form action="${pageContext.request.contextPath}/servlet"> 

    这会产生

     <form action="/contextname/servlet"> 

    这将始终提交到正确的url。


在HTML中使用直引号

您需要确保在HTML属性(如action="..."action='...'使用直引号,从而不像action=”...”action='...'那样使用引号action='...' 在HTML中不支持curl引号,它们将成为值的一部分。

也可以看看:

  • 我们的servlets wiki页面 – 包含一些hello世界的例子
  • 如何从HTML表单调用servlet类
  • doGet和doPost在Servlets中
  • 如何通过单击JSP页面中的超链接或button将当前项传递给Java方法?

其他HTTP状态404错误的情况下:

  • HTTP状态404 – Servlet [ServletName]不可用
  • HTTP状态404 – 请求的资源(/ ProjectName /)不可用
  • HTTP状态404 – 请求的资源(/)不可用
  • / WEB-INF中的JSP返回“HTTP状态404请求的资源不可用”
  • 在JSP文件中引用放置在WEB-INF文件夹中的资源将返回资源上的HTTP 404
  • 当调用转发给JSP的Servlet时,浏览器无法访问/查找CSS,图像和链接等相关资源