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

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

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

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

<form action="/servlet">


<form action="/servlet.java">


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


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


但是这些都不起作用。它们都不断返回HTTP 404错误,例如在Tomcat 6/7/8中:


  HTTP状态404-/ servlet
  
  说明:请求的资源(/ servlet)不可用。


或在Tomcat 8.5 / 9中如下所示:


  HTTP状态404-找不到
  
  讯息:/ servlet
  
  说明:原始服务器找不到目标资源的当前表示,或者不愿意透露该资源的存在


为什么不起作用?

最佳答案

将Servlet类放入package

首先,将servlet类放入Java package中。您应该始终将可公共重用的Java类放在包中,否则它们对于包中的类(例如服务器本身)是不可见的。这样,您就可以消除潜在的特定于环境的问题。无软件包servlet仅在特定的Tomcat + JDK组合中工作,并且永远不应依赖于此。

如果是“普通” IDE项目,则需要将该类放在其包结构中的“ Java Resources”文件夹中,而不是“ WebContent”中,这是针对Web文件(如JSP)的。以下是在导航器视图中看到的默认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中的包结构中。下面是一个默认的Maven webapp项目的文件夹结构示例,如Eclipse的Navigator视图所示:

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之类的路径参数,请改用/servlet/*的URL模式。另见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 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类文件位于其包结构中,位于生产的WAR文件的/WEB-INF/classes文件夹中。对于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是否正确编译并放置在classpath中的一种简单方法是让构建工具生成WAR文件(例如,右键单击项目,在Eclipse中为Export> WAR文件),然后使用ZIP工具检查其内容。如果/WEB-INF/classes中缺少servlet类,则说明该项目配置错误或某些IDE /项目配置默认值被错误地还原(例如,在Eclipse中已禁用了Project> Build Automatically)。如果您没有任何线索,最好是从头开始,并且不要触摸任何IDE /项目配置默认值。

分别测试servlet

前提是服务器在localhost:8080上运行,并且WAR已成功部署在/contextname的上下文路径(默认为IDE项目名称,区分大小写!)上,并且Servlet的初始化未失败(阅读)服务器日志记录任何部署/ servlet成功/失败消息以及实际的上下文路径和servlet映射),然后在/servlet上可以使用URL模式为http://localhost:8080/contextname/servlet的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表单也是毫无意义的。

从HTML引用servlet URL

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

因此,假设HTML表单的JSP页面由http://localhost:8080/contextname/jsps/page.jsp打开,并且您需要提交到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=”...”action=’...’之类的卷曲引号中使用。 HTML不支持使用弯引号,它们只是成为值的一部分。

也可以看看:


Our servlets wiki page-包含一些世界示例
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

关于html - Servlet返回“HTTP状态404请求的资源(/Servlet)不可用”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31175315/

相关文章:

jsp - 如果我没有手动创建 session 对象,如何在我的 jsp 页面中自动创建 session ?

javascript - 使用 jQuery 计算溢出文本的宽度

javascript - Jquery .load 导致按钮点击问题

javascript - 如何在元素上使用滚动条事件

javascript - 如何从 div 容器的开头为列表元素画线?

jQuery:提交动态表单元素时出现问题

php - 不使用 PHP 提交联系表

javascript - Angular 2 动态表单 - 实现清晰的功能

java - 将 Javascript 代码写入来自 Controller 的 HTTP 响应

eclipse - 在 Java 构建路径中找不到父类(super class) "javax.servlet.httpServlet"