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

时间:2012-07-31 00:02:45

标签: html forms jsp servlets http-status-code-404

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

我在HTML表单的action属性中尝试了多个网址:

<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 - 未找到

     

消息:/ servlet

     

说明:原始服务器未找到目标资源的当前表示形式,或者不愿意透露存在该目标资源

为什么不起作用?

17 个答案:

答案 0 :(得分:111)

将servlet类放在package

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

如果是&#34;普通&#34;在IDE项目中,该类需要放在其包内的&#34; Java Resources&#34;文件夹,因此&#34; WebContent&#34;,这适用于JSP等Web文件。下面是 Navigator 视图中显示的默认Eclipse Dynamic Web Project 的文件夹结构示例:

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

如果是Maven项目,则需要将类放在main/java and thus not e.g. main/resources, this is for non-class files内的包结构中。下面是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 root中,但我只是从您的问题中接管这个。

url-pattern

中设置servlet URL

servlet URL被指定为&#34; URL模式&#34; servlet映射。根据定义,它绝对不是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等路径参数,请使用/servlet/*的网址格式。另请参阅Servlet and path parameters like /xyz/{value}/test, how to map in web.xml?

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

为了使用@WebServlet,您只需要确保您的web.xml文件(如果有的话)(自Servlet 3.0以来它是可选的)被声明为符合Servlet 3.0+版本{ {3}}。下面是一个与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 {
    // ...
}

并在web.xml中注册servlet,如下所示:

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

因此请注意,您不应该使用这两种方式。使用基于注释的配置或基于XML的配置。如果同时具有这两种配置,则基于XML的配置将覆盖基于注释的配置。

验证构建/部署

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

  

HTTP状态500

     

实例化servlet类com.example.YourServlet

时出错

在服务器日志中找到java.lang.ClassNotFoundException: com.example.YourServlet,然后是java.lang.NoClassDefFoundError: com.example.YourServlet,然后是javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet

验证servlet是否正确编译并放置在类路径中的一种简单方法是让构建工具生成WAR文件(例如右键单击项目,Eclipse中的 Export&gt; WAR文件)然后使用ZIP工具检查其内容。如果/WEB-INF/classes中缺少servlet类,则项目配置错误或某些IDE /项目配置默认值被错误地还原(例如,Eclipse中已禁用 Project&gt; Build Automatically ) 。如果您没有任何线索,最好从头开始重新启动,不要触摸任何IDE /项目配置默认值。

单独测试servlet

如果服务器在localhost:8080上运行,并且WAR成功部署在/contextname的上下文路径上(默认为IDE项目名称,区分大小写!),并且servlet没有& #39; t初始化失败(读取任何deploy / servlet成功/失败消息的服务器日志以及实际的上下文路径和servlet映射),然后在/servlet处可以使用URL模式为http://localhost:8080/contextname/servlet的servlet 。

您可以直接在浏览器的地址栏中输入,以便对其进行测试。如果正确覆盖并实现了doGet(),那么您将在浏览器中看到其输出。或者,如果您没有doGet()或者错误地拨打super.doGet(),那么&#34; and thus not conform e.g. 2.5 version or lower&#34;将显示错误(仍然优于404,因为405是实际找到servlet本身的证据)。

覆盖service()是一种不好的做法,除非您重新创建MVC框架 - 如果您刚刚开始使用servlet并且对于此处描述的问题一无所知,这是不太可能的。当前问题;)另见HTTP 405: HTTP method GET is not supported by this URL

无论如何,如果servlet在进行静态测试时已经返回404,那么尝试使用HTML表单完全没有意义。从逻辑上讲,将任何HTML表单包含在来自servlet的404错误的问题中也是完全没有意义的。

从HTML

引用servlet URL

一旦您确认servlet在单独调用时工作正常,那么您可以前进到HTML。至于HTML表单的具体问题,<form action>值必须是有效的URL。这同样适用于<a href>。您需要了解绝对/相对URL的工作原理。您知道,URL是一个Web地址,您可以在webbrowser的地址栏中输入/查看。如果您将相对网址指定为表单操作,即没有http://方案,那么它就会与您在webbrowser的地址中看到的当前 URL相关酒吧。因此,绝对不会相对于服务器的WAR文件夹结构中的JSP / HTML文件位置,因为许多初学者似乎都认为。

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

  • 表单操作提交到带有前导斜杠的网址。

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

    这将进入一个文件夹(与本地磁盘文件系统路径完全相同!),因此表单将提交给

    http://localhost:8080/contextname/servlet
    

    这个必须工作!


  • 然而,规范方法是使URL相对于域,这样当您将JSP文件移动到另一个文件夹时,您不需要再次修复URL。

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

    这将生成

    <form action="/contextname/servlet">
    

    因此,它将始终提交到正确的URL。


在HTML

中使用直引号

您需要确保在action="..."action='...'等HTML属性中使用直引号,因此action=”...”等引号或action=’...’。 HTML中不支持卷曲引号,它们只会成为值的一部分。

另见:

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

答案 1 :(得分:1)

方案1::您是在tomcat已已运行时从命令行意外地重新部署

简短答案::停止Tomcat,删除目标文件夹,mvn程序包,然后重新部署


场景2::request.getRequestDispatcher(“ MIS_SPELLED_FILE_NAME .jsp”)

简短答案::检查文件名拼写,确保大小写正确。


方案#3:未找到类异常 (答案在此处,因为:问题号17982240) (java.lang.ClassNotFoundException for servlet in tomcat with eclipse) (被标记为重复并将我定向到此处)

简短答案#3.1:web.xml在servlet类标记中的包路径错误。

简短答案#3.2:java文件导入错误的语句。


下面是方案1的更多详细信息:


1:停止Tomcat

  • 选项1:通过终端中的CTRL + C。
  • 选项2:(tomcat仍在运行时终端已关闭)
  • ------------ 2.1:按: Windows + R ->键入:“ services.msc
  • ------------ 2.2:在列表的“名称”列中找到“ Apache Tomcat#。#Tomcat#”。
  • ------------ 2.3:右键单击->“ 停止

2:删除“目标”文件夹。 (mvn clean不会在这里为您提供帮助)

3:mvn软件包

4: YOUR_DEPLOYMENT_COMMAND_HERE

(我的:java -jar target / dependency / webapp-runner.jar --port 5190 target / *。war)

完整故事:


意外打开一个新的git-bash窗口,然后 尝试通过以下方式为我的heroku项目部署.war文件:

java -jar target / dependency / webapp-runner.jar --port 5190 target / *。war

在部署失败后,我意识到我打开了两个git-bash窗口, 并且未使用CTLR + C停止先前的部署

我遇到了:

  

HTTP状态404 –找不到类型状态报告

     

消息/if-student-test.jsp

     

说明原始服务器未找到当前表示   目标资源或不愿意透露该资源   存在。

     

Apache Tomcat / 8.5.31

下面是方案3的详细信息:


场景3.1:    Servlet类包路径错误    在您的web.xml文件中。

它应该匹配顶部的package语句    您的Java Servlet类。

文件:my_stuff / MyClass.java

   package my_stuff;

文件:PRJ_ROOT / src / main / webapp / WEB-INF / web.xml

   <servlet-class>
   my_stuff.MyClass
   </servlet-class>

场景3.2:

您输入了错误的“ 包装”声明    在myClass.java文件的顶部。

例如:

文件位于:“ / my_stuff ”文件夹中

您错误地写:

package com.my_stuff

这很棘手,因为:

1:Maven版本(mvn软件包)在这里不会报告任何错误。

2:web.xml中的servlet类行可以具有正确的包路径。例如:

<servlet-class>
my_stuff.MyClass
</servlet-class>

使用的堆栈: 记事本++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10

答案 2 :(得分:1)

检查是否输入了Web.xml中指定的正确的URL映射

例如:

在web.xml中,您的servlet声明可能是:

<servlet>
        <servlet-name>ControllerA</servlet-name>
        <servlet-class>PackageName.ControllerA</servlet-class>
</servlet>

<servlet-mapping>
        <servlet-name>ControllerA</servlet-name>
        <url-pattern>/theController</url-pattern>
</servlet-mapping>

此代码段的作用是<url-pattern>/theController</url-pattern>将设置用于通过URL从前端(例如:表单)调用servlet的名称。因此,当您在前端引用servlet时,为了确保请求到达servlet“ ControllerA”,它应从表单中引用指定的URL模式“ theController”。

例如:

<form action="theController" method="POST">
</form>

答案 3 :(得分:0)

首先,以管理员身份运行IDE。之后,右键单击项目文件夹-> Project Facets,并确保Java版本设置正确。在我的电脑上。 (对于示例1.8)现在应该可以工作了。

不仅使用cmd启动服务器,例如Wildfly。它必须在IDE中启动,现在访问您的本地主机URL。示例:http://localhost:8080/HelloWorldServlet/HelloWorld

答案 4 :(得分:0)

如果您使用的是 IntelliJ,这就是为我修复它的原因:

进入Tomcat配置: enter image description here

配置 > 部署选项卡 enter image description here

向下滚动并将 / 添加到应用程序上下文下拉列表 enter image description here

答案 5 :(得分:0)

我也遇到了这个问题,当我访问一个链接到Servlet的URL模式时,我收到了404。原因是因为我有2个Servlet,它们的@WebServlet name参数设置为相同的字符串。

@WebServlet(name = "ServletName", urlPatterns = {"/path"})
public class ServletName extends HttpServlet {}
@WebServlet(name = "ServletName", urlPatterns = {"/other-path"})
public class OtherServletName extends HttpServlet {}

name的两个参数都相同。如果您使用的是name参数,请确保它们与应用程序上的所有其他Servlet相比是唯一的。

答案 6 :(得分:0)

如果您是学生并且是Java的新手,那么您的web.xml文件可能会出现一些问题。

  1. 尝试删除web.xml文件。
  2. 第二次检查您的路径变量是否正确设置。
  3. 重新启动tomcat服务器或您的PC。

您的问题一定会得到解决。

答案 7 :(得分:0)

如果有人在这里使用MySQL,并且认为该代码在前一天可以正常工作,而现在却无法正常工作,那么我猜您必须打开MySQL CLI或MySQL Workbench并仅建立一次数据库连接。一旦连接,数据库也将连接到Java应用程序。我曾经遇到过Hibernate Dialect错误,指出com.mysql.jdbc.Driver有问题。我认为某些计算机上的MySQL存在启动问题。这为我解决了。

答案 8 :(得分:0)

我已经完成了在web.xml中的映射:-

  1. 如果要为新程序制作另一个软件包,那么我们必须提及:-

packagename.filename,介于打开和关闭xml文件中的servlet-class标记之间。

  1. 如果您正在xml中映射文件,但它们无法正常工作或显示错误,请在相应文件中的代码注释行中进行注释。

这两种方法无法相互配合,因此我要么使用创建servlet时提到的文件的注释方法,要么使用映射的方式,然后删除或注释注释行。例如:

 <servlet>
   <servlet-name>s1</servlet-name>
   <servlet-class>performance.FirstServ</servlet-class>
   </servlet>    
   
   <servlet-mapping>
   <servlet-name>s1</servlet-name>
   <url-pattern>/FirstServ</url-pattern>
   </servlet-mapping>
   
   <servlet>
   <servlet-name>s2</servlet-name>
   <servlet-class>performance.SecondServ</servlet-class>
   </servlet>
   
   <servlet-mapping>
   <servlet-name>s2</servlet-name>
   <url-pattern>/SecondServ</url-pattern>
   </servlet-mapping>

如果在xml中完成映射,则对相应文件中的代码注释行进行注释。

//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")

答案 9 :(得分:0)

如果您想在不使用“表单”和“提交”按钮的情况下使用javascript打开Servlet,则以下代码如下:

var button = document.getElementById("<<button-id>>");
button.addEventListener("click", function() {
  window.location.href= "<<full-servlet-path>>" (eg. http://localhost:8086/xyz/servlet)
});

键:

1)button-id:您在html / jsp文件中为按钮赋予的'id'标签。

2)full-servlet-path:单独运行servlet时浏览器中显示的路径

答案 10 :(得分:0)

对我有用的修复方法是(如果使用的是Maven):右键单击您的项目,Maven->更新项目。这可能会给您JDK和其他库(在我的情况下为MySQL连接器)带来其他错误,但是一旦修复它们,您的原始问题就应该得到解决!

答案 11 :(得分:0)

一个旧线程,但是由于我没有在其他地方找到它,因此还有另一种可能性:

如果您使用的是 servlet-api 3.0 + ,则您的web.xml必须包含metadata-complete="true"属性

enter image description here

这告诉tomcat使用web.xml中给出的数据而不是使用@WebServlet注释来映射servlet。

答案 12 :(得分:0)

我删除了旧的Web库,例如spring框架库。并建立图书馆的新路径。然后就可以了。

答案 13 :(得分:0)

执行以下两个步骤。希望能解决Java servlet应用程序开发过程中tomcat服务器中“ 404 not found”的问题。

步骤1:main()

第2步:Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server

答案 14 :(得分:0)

我的问题是我的方法缺少@RequestBody批注。添加注释后,我不再收到404异常。

答案 15 :(得分:0)

在NetBeans IDE中HTTP Status 404的解决方案: 右键单击项目,然后转到项目属性,然后单击运行,然后输入项目相对URL,例如index.jsp

  1. 项目->属性
  2. 点击运行
  3. 相对URL:/index.jsp(选择您的项目根URL)

enter image description here

答案 16 :(得分:-1)

请检查上下文根不能为空

如果您使用的是日食:
右键单击,选择属性,然后选择网络项目设置。选中上下文根不能为空