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

pon*_*ead 82 html forms jsp servlets http-status-code-404

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

action在HTML表单的属性中尝试了几个URL :

<form action="/servlet">
Run Code Online (Sandbox Code Playgroud)
<form action="/servlet.java">
Run Code Online (Sandbox Code Playgroud)
<form action="/src/servlet.java">
Run Code Online (Sandbox Code Playgroud)
<form action="../servlet.java">
Run Code Online (Sandbox Code Playgroud)

但这些都不起作用.他们都在Tomcat 6/7/8中继续返回如下所示的HTTP 404错误:

HTTP状态404 - /servlet

描述:请求的资源(/ servlet)不可用.

或者如下面的Tomcat 8.5/9:

HTTP状态404 - 未找到

消息:/ servlet

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

为什么不起作用?

Bal*_*usC 113

把servlet类放在一个 package

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

对于"普通"IDE项目,该类需要放在"Java Resources"文件夹内的包结构中,因此不是 "WebContent",这适用于JSP等Web文件.下面是一个默认的Eclipse的文件夹结构的示例动态Web项目中看到导航视图:

EclipseProjectName
 |-- src
 |    `-- com
 |         `-- example
 |              `-- YourServlet.java
 |-- WebContent
 |    |-- WEB-INF
 |    |    `-- web.xml
 |    `-- jsps
 |         `-- page.jsp
 :
Run Code Online (Sandbox Code Playgroud)

在一个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
 :
Run Code Online (Sandbox Code Playgroud)

请注意,/jsps子文件夹不是严格必需的.您甚至可以不使用它并将JSP文件直接放在webcontent/webapp root中,但我只是从您的问题中接管这个.

在中设置servlet URL url-pattern

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.
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果您想支持路径参数/servlet/foo/bar,请使用URL模式/servlet/*.另请参阅Servlet和路径参数,如/ xyz/{value}/test,如何在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>
Run Code Online (Sandbox Code Playgroud)

或者,如果您尚未使用Servlet 3.0+(不是Tomcat 7或更新版本,但Tomcat 6或更早版本),则删除@WebServlet注释.

package com.example;

public class YourServlet extends HttpServlet {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

并注册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>
Run Code Online (Sandbox Code Playgroud)

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

验证构建/部署

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

HTTP状态500

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

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

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

单独测试servlet

只要服务器运行localhost:8080,并且WAR成功部署在上下文路径上/contextname(默认为IDE项目名称,区分大小写!),并且servlet未初始化失败(读取任何部署的服务器日志/的servlet成功/失败消息和实际上下文路径和servlet映射),则用的URL模式的servlet /servlet提供的http://localhost:8080/contextname/servlet.

您可以直接在浏览器的地址栏中输入它,以便对其进行测试.如果它doGet()被正确覆盖并实现,那么您将在浏览器中看到它的输出.或者,如果您没有任何doGet()错误或者错误调用super.doGet(),那么将显示" 此URL不支持HTTP 405:HTTP方法GET "错误(这仍然优于404,因为405是servlet的证据)实际上是找到了).

覆盖service()是一种不好的做法,除非你重新发明一个MVC框架 - 如果你刚刚开始使用servlet并且对当前问题中描述的问题毫无头绪,这是不太可能的;)另见Design Patterns基于Web的应用程序.

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

从HTML引用servlet URL

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

因此,假设与HTML表单的JSP页面被打开http://localhost:8080/contextname/jsps/page.jsp,你需要提交给位于一个servlet http://localhost:8080/contextname/servlet,下面是一些例子(注意,您可以安全地代替<form action><a href>在这里):

在HTML中使用直引号

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

也可以看看:

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


J.M*_*SON 5

场景 #1:当 tomcat已经运行时,您意外地从命令行重新部署

\n\n

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

\n\n
\n\n

场景 #2: request.getRequestDispatcher(" MIS_SPELLED_FILE_NAME .jsp")

\n\n

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

\n\n
\n\n

场景 #3:类未找到异常\n(答案放在这里,因为:问题# 17982240 )\n(java.lang.ClassNotFoundException for servlet in tomcat with eclipse)\n(被标记为重复并引导我到这里)

\n\n

简短回答#3.1:web.xml servlet-class 标记中的包路径错误。

\n\n

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

\n\n
\n\n

以下是场景 #1 的更多详细信息:

\n\n
\n\n

1:停止Tomcat

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

2: 删除“target”文件夹。\n (mvn clean 在这里不会帮助你)

\n\n

3:mvn包

\n\n

4:您的部署命令在这里

\n\n

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

\n\n

完整的背景故事:

\n\n
\n\n

不小心打开了一个新的 git-bash 窗口并尝试通过以下方式为我的 heroku 项目部署 .war 文件:

\n\n

java -jar 目标/依赖/webapp-runner.jar --端口 5190 目标/*.war

\n\n

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

\n\n

我遇到了:

\n\n
\n

HTTP 状态 404 \xe2\x80\x93 未找到类型状态报告

\n\n

消息/if-student-test.jsp

\n\n

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

\n\n

阿帕奇 Tomcat/8.5.31

\n
\n\n

以下是场景 #3 的更多详细信息:

\n\n
\n\n

场景 3.1:\n web.xml 文件中的 servlet 类包路径错误。

\n\n

它应该与 java servlet 类顶部的 package 语句匹配。

\n\n

文件:my_stuff/ MyClass.java

\n\n
   package my_stuff;\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
   <servlet-class>\n   my_stuff.MyClass\n   </servlet-class>\n
Run Code Online (Sandbox Code Playgroud)\n\n

场景 3.2:

\n\n

您在 myClass.java 文件顶部放置了错误的“ package ”语句\n。

\n\n

例如:

\n\n

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

\n\n

你错误地写了:

\n\n
package com.my_stuff\n
Run Code Online (Sandbox Code Playgroud)\n\n

这很棘手,因为:

\n\n

1:maven构建(mvn包)这里不会报任何错误。

\n\n

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

\n\n
<servlet-class>\nmy_stuff.MyClass\n</servlet-class>\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

使用的堆栈:\n Notepad++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :

\n


归档时间:

查看次数:

99959 次

最近记录:

6 年,8 月 前