gpt4 book ai didi

java - Servlet 返回 "HTTP Status 404 The requested resource (/servlet) is not available"

转载 作者:行者123 更新时间:2023-12-03 05:11:23 25 4
gpt4 key购买 nike

我的 WebContent/jsps 中的 JSP 文件中有一个 HTML 表单文件夹。我有一个 servlet 类 servlet.java在我的默认包中 src文件夹。在我的 web.xml它被映射为 /servlet .
我在 action 中尝试了几个 URL HTML 表单的属性:

<form action="/servlet">
<form action="/servlet.java">
<form action="/src/servlet.java">
<form action="../servlet.java">
但这些都不起作用。它们都在 Tomcat 6/7/8 中不断返回 HTTP 404 错误,如下所示:

HTTP Status 404 — /servlet

Description: The requested resource (/servlet) is not available.


或者在 Tomcat 8.5/9 中如下:

HTTP Status 404 — Not Found

Message: /servlet

Description: The origin server did not find a current representation for the target resource or is not willing to disclose that one exists


为什么它不起作用?

最佳答案

简介
这可能有很多原因,在以下部分中分割:

  • 将 servlet 类放入 package
  • url-pattern 中设置 servlet URL
  • @WebServlet仅适用于 Servlet 3.0 或更高版本
  • javax.servlet.*在 Servlet 5.0 或更新版本中不再工作
  • 确保编译 *.class文件存在于构建的 WAR 中
  • 在没有任何 JSP/HTML 页面的情况下单独测试 servlet
  • 使用域相对 URL 从 HTML 引用 servlet
  • 在 HTML 属性中使用直引号

  • 将 servlet 类放入 package首先,将servlet类放在一个Java中 package .您应该始终将可公开重用的 Java 类放在包中,否则它们对于包中的类(例如服务器本身)是不可见的。这样您就可以消除潜在的特定于环境的问题。无包 servlet 仅在特定的 Tomcat + JDK 组合中工作,并且永远不应依赖于此。
    对于“普通”IDE 项目,该类需要放置在“Java Sources”文件夹内的包结构中,而不是“Web Content”文件夹内,后者用于 Web 文件,例如 JSP。以下是在导航器 View 中看到的默认 Eclipse 动态 Web 项目的文件夹结构示例(“Java Sources”文件夹在此类项目中默认由 src 文件夹表示):
    EclipseProjectName
    |-- src
    | `-- com
    | `-- example
    | `-- YourServlet.java
    |-- WebContent
    | |-- WEB-INF
    | | `-- web.xml
    | `-- jsps
    | `-- page.jsp
    :
    对于 Maven 项目,该类需要放置在其包结构中 main/java因此不是 main/resources , this is for non-class files也绝对不是 main/webapp ,这是用于网络文件。下面是在 Eclipse 的导航器 View 中看到的默认 Maven webapp 项目的文件夹结构示例:
    MavenProjectName
    |-- src
    | `-- main
    | |-- java
    | | `-- com
    | | `-- example
    | | `-- YourServlet.java
    | |-- resources
    | `-- webapp
    | |-- WEB-INF
    | | `-- web.xml
    | `-- jsps
    | `-- page.jsp
    :
    请注意 /jsps子文件夹不是绝对必要的。您甚至可以不使用它并将 JSP 文件直接放在 webcontent/webapp 根目录中,但我只是从您的问题中接管了这个。
    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 ,然后使用 URL 模式 /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+ 版本 and thus not conform e.g. 2.5 version or lower .下面是一个兼容 Servlet 4.0 的(匹配 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>
    或者,如果您还没有使用 Servlet 3.0+(例如 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 的配置将覆盖基于注解的配置。 javax.servlet.*在 Servlet 5.0 或更新版本中不再工作
    从 Jakarta EE 9/Servlet 5.0(Tomcat 10、TomEE 9、WildFly 22 Preview、GlassFish 6、Payara 6、Liberty 22 等)开始, javax.*包已重命名为 jakarta.*包。
    换句话说,请绝对确保您不会为了得到 javax.*而随意将不同服务器的JAR文件(例如tomcat-servlet-api-9.x.x.jar)放入您的WAR项目中。要编译的包。这只会带来麻烦。完全删除它并编辑您的 servlet 类的导入
    import javax.servlet.*;
    import javax.servlet.http.*;

    import jakarta.servlet.*;
    import jakarta.servlet.http.*;
    如果您使用 Maven,您可以找到正确的示例 pom.xml Tomcat 10+、Tomcat 9-、JEE 9+ 和 JEE 8- 的声明: Tomcat casting servlets to javax.servlet.Servlet instead of jakarta.servlet.http.HttpServlet
    确保编译 *.class文件存在于构建的 WAR 中
    如果您正在使用诸如 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 Status 500

    Error instantiating servlet class 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 中的导出 > WAR 文件),然后使用 ZIP 工具检查其内容。如果 /WEB-INF/classes 中缺少 servlet 类,或者如果导出导致错误,则项目配置不当或某些 IDE/项目配置默认值被错误地恢复(例如,项目 > 自动构建已在 Eclipse 中禁用)。
    您还需要确保项目图标没有表示构建错误的红叉。您可以在问题 View (窗口 > 显示 View > 其他...)中找到确切的错误。通常错误信息是好的 Googlable。如果您不知道,最好从头开始,不要触及任何 IDE/项目配置默认值。如果您使用 Eclipse,您可以在 How do I import the javax.servlet / jakarta.servlet API in my Eclipse project? 中找到说明。
    在没有任何 JSP/HTML 页面的情况下单独测试 servlet
    前提是服务器运行在 localhost:8080 ,并且 WAR 已成功部署在 /contextname 的上下文路径上(默认为 IDE 项目名称,区分大小写!),并且 servlet 没有失败其初始化(读取任何部署/servlet 成功/失败消息的服务器日志以及实际上下文路径和 servlet 映射),然后是一个带有 /servlet的网址格式可在 http://localhost:8080/contextname/servlet 获得.
    您可以直接在浏览器的地址栏中输入它以进行单独测试。如果它的 doGet()被正确覆盖和实现,然后您将在浏览器中看到它的输出。或者如果您没有任何 doGet()或者如果它错误地调用 super.doGet() ,然后将显示“ HTTP 405: HTTP method GET is not supported by this URL ”错误(这仍然比 404 好,因为 405 证明确实找到了 servlet 本身)。
    覆盖 service()是一种不好的做法,除非您正在重新发明一个 MVC 框架——如果您刚开始使用 servlet 并且对当前问题中描述的问题一无所知,这是不太可能的;) 另请参阅 Design Patterns web based applications .
    无论如何,如果 servlet 在单独测试时已经返回 404,那么尝试使用 HTML 表单是完全没有意义的。因此,从逻辑上讲,在有关 servlet 的 404 错误的问题中包含任何 HTML 表单也是完全没有意义的。
    使用域相对 URL 从 HTML 引用 servlet
    一旦您确认 servlet 在单独调用时工作正常,您就可以继续使用 HTML。至于您使用 HTML 表单的具体问题, <form action>值必须是有效的 URL。这同样适用于 <a href> .您需要了解绝对/相对 URL 的工作原理。您知道,URL 是一个网址,您可以在网络浏览器的地址栏中输入/查看。如果您将相对 URL 指定为表单操作,即没有 http://方案,那么它就相对于您在网络浏览器地址栏中看到的当前 URL。因此,它绝对与许多初学者似乎认为的服务器 WAR 文件夹结构中的 JSP/HTML 文件位置无关。
    因此,假设带有 HTML 表单的 JSP 页面是由 http://localhost:8080/contextname/jsps/page.jsp 打开的。 (因此 不是 by file://... ),并且您需要提交到位于 http://localhost:8080/contextname/servlet 的 servlet ,这里有几种情况(请注意,您可以安全地将 <form action> 替换为 <a href> 此处):
  • 表单操作提交到带有前导斜杠的 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">
    这将向上移动一个文件夹(就像在本地磁盘文件系统路径中一样!),因此表单将提交到
      http://localhost:8080/contextname/servlet
    这个必须管用!

  • 然而,规范的方法是使 URL 与域相关,这样当您碰巧将 JSP 文件移动到另一个文件夹时,您不需要再次修复 URL。
      <form action="${pageContext.request.contextPath}/servlet">
    这将产生
      <form action="/contextname/servlet">
    因此,这将始终提交到正确的 URL。


  • 在 HTML 属性中使用直引号
    您需要确保在 HTML 属性中使用直引号,例如 action="..."action='...'因此不是像 action=”...” 这样的 curl 引号或 action=’...’ . HTML 中不支持 curl 引号,它们将简单地成为值的一部分。从博客中复制粘贴代码片段时要小心!众所周知,一些博客引擎,特别是 Wordpress,默认使用所谓的“智能引号”,因此也会以这种方式破坏代码片段中的引号。另一方面,不要复制粘贴代码,而是尝试自己键入代码。通过您的大脑和手指实际获取代码的另一个好处是,它会让您长期更好地记住和理解代码,并使您成为更好的开发人员。
    另见:
  • Our servlets wiki page - 包含一些 hello world 示例
  • How to call servlet class from HTML form
  • doGet and doPost in Servlets
  • How do I pass current item to Java method by clicking a hyperlink or button in JSP page?

  • HTTP 状态 404 错误的其他情况:
  • HTTP Status 404 - Servlet [ServletName] is not available
  • HTTP Status 404 - The requested resource (/ProjectName/) is not available
  • HTTP Status 404 - The requested resource (/) is not available
  • JSP in /WEB-INF returns "HTTP Status 404 The requested resource is not available"
  • Referencing a resource placed in WEB-INF folder in JSP file returns HTTP 404 on resource
  • Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
  • 关于java - Servlet 返回 "HTTP Status 404 The requested resource (/servlet) is not available",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11731377/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com