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。在我的web.xml中,它被映射为/servlet 我在HTML表单的action属性中尝试了几个URL: 但这些都不管用。它们都不断返回HTTP 404错误,如Tomcat 6/7/8中的以下错误: HTTP状态404-/servlet 描述:请求的资源(/servlet)不可用 或如Tomcat 8.5/9中所述: HTTP状
WebContent/jsps
文件夹中的JSP文件中有一个HTML表单。我在src
文件夹中的默认包中有一个servlet类servlet.java
。在我的web.xml
中,它被映射为/servlet
我在HTML表单的action
属性中尝试了几个URL:
但这些都不管用。它们都不断返回HTTP 404错误,如Tomcat 6/7/8中的以下错误:
HTTP状态404-/servlet
描述:请求的资源(/servlet)不可用
或如Tomcat 8.5/9中所述:
HTTP状态404-未找到
消息:/servlet
描述:源服务器找不到目标资源的当前表示形式,或者不愿意透露存在该表示形式
为什么不起作用?导言
这可能有很多原因,这些原因在以下章节中进行了分解:
- 将servlet类放入
包中
- 在
URL模式中设置servlet URL
仅适用于Servlet 3.0或更高版本@WebServlet
在servlet 5.0或更高版本中不再工作javax.servlet.*
- 确保编译的
文件存在于内置WAR中*.class
- 在没有任何JSP/HTML页面的情况下单独测试servlet
- 使用域相对URL从HTML引用servlet
- 在HTML属性中使用直接引号
包中
首先,将servlet类放入Java包中。您应该始终将可公开重用的Java类放在包中,否则它们对包中的类(例如服务器本身)是不可见的。这样可以消除潜在的特定于环境的问题。无包servlet只能在特定的Tomcat+JDK组合中工作,这是不应该依赖的
对于“普通”IDE项目,类需要放在其包结构中的“Java源代码”文件夹中,而不是放在“Web内容”文件夹中,该文件夹用于JSP等Web文件。下面是在Navigator视图中看到的默认Eclipse动态Web项目的文件夹结构示例(“Java源代码”文件夹默认位于该项目中,由src
文件夹表示):
EclipseProjectName
|--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
,则使用URL模式/servlet/*
。另见
@WebServlet
仅适用于Servlet 3.0或更高版本
为了使用@WebServlet
,您只需要确保您的web.xml
文件(如果有)(自Servlet 3.0以来是可选的)声明为符合Servlet 3.0+版本。下面是一个与Servlet 4.0兼容的版本(与Tomcat 9+、WildFly 11+、Payara 5+等匹配)
并在web.xml
中注册servlet,如下所示:
yourServlet
com.example.YourServlet
yourServlet
/servlet
因此请注意,您不应同时使用这两种方法。使用基于注释的配置或基于XML的配置。如果两者都有,则基于XML的配置将覆盖基于注释的配置
javax.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类的导入
import javax.servlet.*;
导入javax.servlet.http.*;
到
import 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.ex
package com.example;
public class YourServlet extends HttpServlet {
// ...
}
package my_stuff;
<servlet-class>
my_stuff.MyClass
</servlet-class>
package com.my_stuff
<servlet-class>
my_stuff.MyClass
</servlet-class>
var button = document.getElementById("<<button-id>>");
button.addEventListener("click", function() {
window.location.href= "<<full-servlet-path>>" (eg. http://localhost:8086/xyz/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>
//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")
<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>