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

Java Servlet返回“HTTP状态404请求的资源(/Servlet)不可用”,java,forms,jsp,servlets,http-status-code-404,Java,Forms,Jsp,Servlets,Http Status Code 404,我在WebContent/jsps文件夹中的JSP文件中有一个HTML表单。我在src文件夹中的默认包中有一个servlet类servlet.java。在my web.xml中,它被映射为/servlet 我尝试了HTML表单的几个URL-in-action属性: 但这些都不管用。它们都不断返回HTTP 404错误,如Tomcat 6/7/8中的以下错误: HTTP状态404-/servlet 描述:请求的资源/servlet不可用 或如Tomcat 8.5/9中所述: HTTP状态404-未找

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

我尝试了HTML表单的几个URL-in-action属性:

但这些都不管用。它们都不断返回HTTP 404错误,如Tomcat 6/7/8中的以下错误:

HTTP状态404-/servlet 描述:请求的资源/servlet不可用

或如Tomcat 8.5/9中所述:

HTTP状态404-未找到 消息:/servlet

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

为什么不起作用?

导言 这可能有很多原因,这些原因在以下章节中进行了分解:

将servlet类放入包中 在URL模式中设置servlet URL @WebServlet仅适用于Servlet 3.0或更新版本 servlet.*在servlet 5.0或更新版本中不再工作 确保编译的*.class文件存在于内置WAR中 在没有任何JSP/HTML页面的情况下单独测试servlet 使用域相对URL从HTML引用servlet 在HTML属性中使用直接引号 将servlet类放入包中 首先,将servlet类放入Java包中。您应该始终将可公开重用的Java类放在包中,否则它们对包中的类(例如服务器本身)是不可见的。这样可以消除潜在的特定于环境的问题。无包servlet只能在特定的Tomcat+JDK组合中工作,这是不应该依赖的

对于普通IDE项目,类需要放在Java Sources文件夹中的包结构中,而不是放在Web内容文件夹中,Web内容文件夹用于JSP等Web文件。下面是默认Eclipse动态Web项目的文件夹结构示例,如Navigator视图中所示,Java Sources文件夹默认位于该项目中,由src folder表示:

日食项目名称 |-src |`-com |`-例如 |`-YourServlet.java |-网络内容 ||-WEB-INF ||`-web.xml |`-JSP |`-page.jsp : 对于Maven项目,该类需要放在main/java内部的包结构中,因此不是main/resources,也绝对不是main/webapp,这是针对web文件的。下面是在Eclipse的Navigator视图中看到的默认Maven webapp项目的文件夹结构示例:

MavenProjectName |-src |`-主要 ||-java ||`-com ||`—示例 ||`-YourServlet.java ||-资源 |`-webapp ||-WEB-INF ||`-web.xml |`-JSP |`-page.jsp : 请注意,/jsps子文件夹并不是绝对必要的。您甚至可以不使用它,直接将JSP文件放在webcontent/webapp根目录中,但我只是从您的问题中接过这个问题

在URL模式中设置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.
    // ...
}
package com.example;

public class YourServlet extends HttpServlet {
    // ...
}
如果您想支持/servlet/foo/bar之类的路径参数,那么可以使用/servlet/*的URL模式。另见

@WebServlet仅适用于Servlet 3.0或更新版本 为了使用@WebServlet,您只需要确保您的web.xml文件(如果有)声明为符合Servlet 3.0+版本,因为Servlet 3.0是可选的。下面是一个与Servlet 4.0兼容的Servlet,它与Tomcat 9+、WildFly 11+、Payara 5+等匹配

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    version="4.0"
>
    <!-- Config here. -->
</web-app>
并在web.xml中注册servlet,如下所示:

yourServlet com.example.YourServlet yourServlet /servlet 因此请注意,您不应同时使用这两种方法。使用基于注释的配置或基于XML的配置。如果两者都有,则基于XML的配置将覆盖基于注释的配置

servlet.*在servlet 5.0或更新版本中不再工作 自雅加达EE 9/Servlet 5.0 Tomcat 10、TomEE 9、WildFly 22预览版、GlassFish 6、Payara 6、Liberty 22等以来,javax.*包已重命名为Jakarta.*包

换句话说,请绝对确保不要仅仅为了编译javax.*包而在WAR项目中随机放置不同服务器的JAR文件,例如tomcat-servlet-api-9.x.x.JAR。这只会带来麻烦。将其全部删除,并从中编辑servlet类的导入

导入javax.servlet.*; 导入javax.servlet.http.*; 到

导入jakarta.servlet.*; 导入jakarta.servlet.http.*; 如果您使用的是Maven,您可以在以下答案中找到Tomcat 10+、Tomcat 9-、JEE 9+和JEE 8-的正确pom.xml声明示例:

确保 编译的*.class文件存在于内置WAR中 如果您使用的是Eclipse和/或Maven等构建工具,那么您需要绝对确保编译的servlet类文件位于生成的WAR文件的/WEB-INF/classes文件夹中的包结构中。如果是包com.example;公共类YourServlet,它必须位于/WEB-INF/classes/com/example/YourServlet.class中。否则,在@WebServlet出现404错误或HTTP 500错误时,您将面临如下情况:

HTTP状态500 实例化servlet类com.example.YourServlet时出错

并在服务器日志中找到一个java.lang.ClassNotFoundException:com.example.YourServlet,后跟一个java.lang.NoClassDefFoundError:com.example.YourServlet,依次是javax.servlet.ServletException:Error实例化servlet类com.example.YourServlet

验证servlet是否正确编译并放置在类路径中的一种简单方法是让构建工具生成WAR文件,例如,在Eclipse中右键单击项目、导出>WAR文件,然后使用ZIP工具检查其内容。如果/WEB-INF/classes中缺少servlet类,或者导出导致错误,则说明项目配置不正确,或者错误地恢复了某些IDE/project配置默认值,例如在Eclipse中禁用了project>Build Automatically

您还需要确保项目图标没有表示生成错误的红十字。您可以在问题视图窗口>显示视图>其他…中找到确切的错误。。。。通常错误消息是很好的Googlable。若你们并没有任何线索,最好是从头开始,不要碰任何IDE/项目配置默认值。如果您使用的是Eclipse,您可以在

在没有任何JSP/HTML页面的情况下单独测试servlet 假设服务器在localhost:8080上运行,并且WAR成功部署在/contextname的上下文路径上,该路径默认为IDE项目名称,区分大小写!,如果servlet没有初始化失败,则可以读取服务器日志中的任何部署/servlet成功/失败消息以及实际的上下文路径和servlet映射,然后在http://localhost:8080/contextname/servlet.

您可以直接在浏览器的地址栏中输入它,以不受干扰的方式进行测试。若它的doGet被正确覆盖和实现,那个么您将在浏览器中看到它的输出。或者,如果您没有任何doGet,或者它错误地调用super.doGet,那么将显示一个错误,该错误仍然比404好,因为405是实际找到servlet本身的证据

重写服务是一种糟糕的做法,除非您正在重新创建一个MVC框架——如果您刚开始使用servlet,并且对当前问题中描述的问题一无所知,这是不可能的;另见

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

使用域相对URL从HTML引用servlet 一旦您验证了servlet在单独调用时工作正常,那么就可以进入HTML。至于HTML表单的具体问题,该值必须是有效的URL。这同样适用于-包含一些hello world示例 HTTP状态404错误的其他情况: NetBeans IDE中HTTP状态404的解决方案: 右键单击项目并转到项目属性,然后单击运行,然后输入项目相对URL,如index.jsp

项目->属性 点击Run 相对URL:/index.jsp选择项目根URL 场景1:当tomcat已经运行时,您意外地从命令行重新部署

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

场景2:request.getRequestDispatcherMIS\u拼写文件\u NAME.jsp

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

场景3:未找到类异常 答案放在这里是因为:问题17982240 被标记为重复并指示我在这里

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

简短回答3.2:java文件有错误的导入语句

下面是场景1的进一步详细信息: 1:阻止雄猫

选项1:通过终端中的CTRL+C。 选项2:终端关闭,而tomcat仍在运行 ------2.1:按:Windows+R->type:services.msc ------2.2:查找ApacheTomcat。列表名称列中的Tomcat。 ------2.3:右键单击->停止 2:删除目标文件夹。 mvn clean在这里帮不了你

3:mvn包

4:您的部署命令在这里

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

背景故事:

意外地打开了一个新的git bash窗口 试图部署.war文件f 或我的heroku项目,通过:

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

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

我会见了:

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

Message/if-student-test.jsp

说明源服务器未找到当前表示形式 对于目标资源,或不愿意披露该资源 存在

ApacheTomcat/8.5.31

下面是场景3的进一步详细信息: 情景3.1: servlet类包路径错误 在web.xml文件中

它应该与顶部的package语句匹配 您的Javaservlet类

文件:my_stuff/MyClass.java:

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

这很棘手,因为:

1:maven build mvn包不会在此处报告任何错误

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

<servlet-class>
my_stuff.MyClass
</servlet-class>
使用的堆栈:
记事本+++GitBash+Maven+Heroku Web App Runner+Tomcat9+Windows10:

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

执行以下两个步骤。我希望在开发JavaServlet应用程序的过程中,它能解决tomcat服务器中404未找到的问题

步骤1:右键单击服务器资源管理器选项卡->属性->将位置从工作区元数据切换到tomcat服务器中的服务器


步骤2:双击服务器资源管理器选项卡中的服务器->选择服务器位置菜单中的使用tomcat安装选项

我删除了旧的web库,例如spring框架库。构建图书馆的新路径。然后它就会工作。

请检查上下文根不能为空

如果您使用的是eclipse:
单击鼠标右键,选择“属性”,然后选择“web项目设置”。检查上下文根不能为空

一个旧线程,但由于我在别处没有找到它,这里还有一种可能性:

如果您使用的是servlet api 3.0+,那么web.xml不能包含metadata complete=true属性


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

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

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.
    // ...
}
package com.example;

public class YourServlet extends HttpServlet {
    // ...
}

不要仅仅使用cmd启动服务器,例如Wildfly。它必须在IDE中启动,现在可以访问您的本地主机URL。示例:

如果您正在使用Maven,对我有效的修复方法是:右键单击您的项目,Maven->Update project。这可能会给您带来JDK和其他库的一些其他错误在我的例子中,MySQL连接器,但一旦您修复了它们,您的原始问题就应该得到修复

如果您希望在不使用“表单”和“提交”按钮的情况下使用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按钮id:在html/jsp文件中为按钮提供的“id”标记


2完整servlet路径:在web.xml中单独运行servlet映射时,浏览器中显示的路径就是我所做的:-

如果有其他针对新项目的软件包,那么我们必须提到:- xml文件中servlet类标记的打开和关闭之间的packagename.filename

如果您正在用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>

如果有人在这里使用MySQL,并且觉得代码在前一天起作用,而现在不起作用,那么我想您必须打开MySQL CLI或MySQL Workbench,只需连接一次数据库。一旦连接,数据库也会连接到Java应用程序。我过去常常遇到Hibernate方言错误,指出com.mysql.jdbc.Driver有问题。我认为MySQL在某些计算机上有启动问题。这对我来说已经解决了。

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

尝试删除web.xml文件。 其次,检查路径变量是否正确设置。 重新启动tomcat服务器或PC。
您的问题肯定会得到解决。

检查您是否输入了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>
此代码段所做的是/thecontroller将设置用于从前端调用servlet的名称,例如:form通过URL。因此,当您在前端引用servlet时,为了确保请求转到servlet Co controllera,它应该从表单中引用控制器指定的URL模式

例如:


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

@WebServletname=ServletName,urlPatterns={/path} 公共类ServletName扩展了HttpServlet{} @WebServletname=ServletName,urlPatterns={/other path} 公共类OtherServletName扩展了HttpServlet{}
两个名称参数都相同。如果您使用的是name参数,请确保它们与应用程序上的所有其他servlet相比是唯一的。

我也有同样的问题。尝试了所有这些,但没有帮助。通过在xml文件的开头和结尾添加元素标记,我成功地解决了这个问题。我将在下面留下我的xml文件以供参考

<?xml version="1.0" encoding="UTF-8"?>

<element>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
     
<servlet> 
    <servlet-name>InsertServlet</servlet-name> 
    <servlet-class>com.worklog.InsertServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>InsertServlet</servlet-name> 
    <url-pattern>/insert</url-pattern> 
</servlet-mapping>

</web-app>

</element>

web app version=3.1使用glassfish,当我在web.xml和注释中有一个映射时,我可以单独测试我的servlet。我删除了映射并保留了注释,因为我有最新的版本,但是我会得到一个404错误?如果您在webapp本身中包含servlet 2.5或更旧的库,而不是依靠目标运行时自己提供servlet库,则可能会发生这种情况。您的AppName.war和分解的文件夹名称不匹配您期望的名称,例如,当您的war文件的版本为AppName-1.0-SNAPSHOT.war,并且您正在尝试/AppName/。
<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>
<form action="theController" method="POST">
</form>
<?xml version="1.0" encoding="UTF-8"?>

<element>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
     
<servlet> 
    <servlet-name>InsertServlet</servlet-name> 
    <servlet-class>com.worklog.InsertServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>InsertServlet</servlet-name> 
    <url-pattern>/insert</url-pattern> 
</servlet-mapping>

</web-app>

</element>