我的WebContent/jsps
文件夹中的JSP文件中有一个HTML表单。我在servlet.java
文件夹中的默认包中有一个servlet类src
。在我的web.xml
中,它被映射为/servlet
。
我在HTML表单的action
属性中尝试了多个网址:
<form action="/servlet">
<form action="/servlet.java">
<form action="/src/servlet.java">
<form action="../servlet.java">
但这些都没有奏效。他们都在Tomcat 6/7/8中继续返回如下所示的HTTP 404错误:
HTTP状态404 - / servlet
描述:请求的资源(/ servlet)不可用。
或者如下面的Tomcat 8.5 / 9:
HTTP状态404 - 未找到
消息:/ servlet
说明:原始服务器未找到目标资源的当前表示形式,或者不愿意透露存在该目标资源
为什么不起作用?
答案 0 :(得分:111)
package
首先,将servlet类放在Java package
中。您应该始终将公开可重用的Java类放在一个包中,否则它们对于包中的类是不可见的,例如服务器本身。这样就可以消除潜在的特定于环境的问题。无包装servlet仅在特定的Tomcat + JDK组合中起作用,绝不应该依赖它。
如果是&#34;普通&#34;在IDE项目中,该类需要放在其包内的&#34; Java Resources&#34;文件夹,因此不&#34; WebContent&#34;,这适用于JSP等Web文件。下面是 Navigator 视图中显示的默认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内的包结构中。下面是Eclipse的 Navigator 视图中默认的Maven webapp项目的文件夹结构示例:
MavenProjectName
|-- src
| `-- main
| |-- java
| | `-- com
| | `-- example
| | `-- YourServlet.java
| |-- resources
| `-- webapp
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
请注意,/jsps
子文件夹并非绝对必要。您甚至可以不使用它并将JSP文件直接放在webcontent / webapp root中,但我只是从您的问题中接管这个。
url-pattern
servlet URL被指定为&#34; URL模式&#34; servlet映射。根据定义,它绝对不是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/*
的网址格式。另请参阅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+版本{ {3}}。下面是一个与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类文件位于其生成的/WEB-INF/classes
文件夹中的包结构中WAR文件。如果是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是否正确编译并放置在类路径中的一种简单方法是让构建工具生成WAR文件(例如右键单击项目,Eclipse中的 Export&gt; WAR文件)然后使用ZIP工具检查其内容。如果/WEB-INF/classes
中缺少servlet类,则项目配置错误或某些IDE /项目配置默认值被错误地还原(例如,Eclipse中已禁用 Project&gt; Build Automatically ) 。如果您没有任何线索,最好从头开始重新启动,不要触摸任何IDE /项目配置默认值。
如果服务器在localhost:8080
上运行,并且WAR成功部署在/contextname
的上下文路径上(默认为IDE项目名称,区分大小写!),并且servlet没有& #39; t初始化失败(读取任何deploy / servlet成功/失败消息的服务器日志以及实际的上下文路径和servlet映射),然后在/servlet
处可以使用URL模式为http://localhost:8080/contextname/servlet
的servlet 。
您可以直接在浏览器的地址栏中输入,以便对其进行测试。如果正确覆盖并实现了doGet()
,那么您将在浏览器中看到其输出。或者,如果您没有doGet()
或者错误地拨打super.doGet()
,那么&#34; and thus not conform e.g. 2.5 version or lower&#34;将显示错误(仍然优于404,因为405是实际找到servlet本身的证据)。
覆盖service()
是一种不好的做法,除非您重新创建MVC框架 - 如果您刚刚开始使用servlet并且对于此处描述的问题一无所知,这是不太可能的。当前问题;)另见HTTP 405: HTTP method GET is not supported by this URL。
无论如何,如果servlet在进行静态测试时已经返回404,那么尝试使用HTML表单完全没有意义。从逻辑上讲,将任何HTML表单包含在来自servlet的404错误的问题中也是完全没有意义的。
一旦您确认servlet在单独调用时工作正常,那么您可以前进到HTML。至于HTML表单的具体问题,<form action>
值必须是有效的URL。这同样适用于<a href>
。您需要了解绝对/相对URL的工作原理。您知道,URL是一个Web地址,您可以在webbrowser的地址栏中输入/查看。如果您将相对网址指定为表单操作,即没有http://
方案,那么它就会与您在webbrowser的地址中看到的当前 URL相关酒吧。因此,绝对不会相对于服务器的WAR文件夹结构中的JSP / HTML文件位置,因为许多初学者似乎都认为。
因此,假设带有HTML表单的JSP页面由http://localhost:8080/contextname/jsps/page.jsp
打开,并且您需要提交到位于http://localhost:8080/contextname/servlet
的servlet,这里有几种情况(请注意,您可以安全地替换这里有<form action>
<a href>
:
表单操作提交到带有前导斜杠的网址。
<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。
您需要确保在action="..."
或action='...'
等HTML属性中使用直引号,因此不等action=”...”
等引号或action=’...’
。 HTML中不支持卷曲引号,它们只会成为值的一部分。
答案 1 :(得分:1)
方案1::您是在tomcat已已运行时从命令行意外地重新部署。
简短答案::停止Tomcat,删除目标文件夹,mvn程序包,然后重新部署
场景2::request.getRequestDispatcher(“ MIS_SPELLED_FILE_NAME .jsp”)
简短答案::检查文件名拼写,确保大小写正确。
方案#3:未找到类异常 (答案在此处,因为:问题号17982240) (java.lang.ClassNotFoundException for servlet in tomcat with eclipse) (被标记为重复并将我定向到此处)
简短答案#3.1:web.xml在servlet类标记中的包路径错误。
简短答案#3.2:java文件导入错误的语句。
1:停止Tomcat
2:删除“目标”文件夹。 (mvn clean不会在这里为您提供帮助)
3:mvn软件包
4: YOUR_DEPLOYMENT_COMMAND_HERE
(我的:java -jar target / dependency / webapp-runner.jar --port 5190 target / *。war)
完整故事:
意外打开一个新的git-bash窗口,然后 尝试通过以下方式为我的heroku项目部署.war文件:
java -jar target / dependency / webapp-runner.jar --port 5190 target / *。war
在部署失败后,我意识到我打开了两个git-bash窗口, 并且未使用CTLR + C停止先前的部署。
我遇到了:
HTTP状态404 –找不到类型状态报告
消息/if-student-test.jsp
说明原始服务器未找到当前表示 目标资源或不愿意透露该资源 存在。
Apache Tomcat / 8.5.31
场景3.1: Servlet类包路径错误 在您的web.xml文件中。
它应该匹配顶部的package语句 您的Java Servlet类。
文件:my_stuff / MyClass.java :
package my_stuff;
文件:PRJ_ROOT / src / main / webapp / WEB-INF / web.xml
<servlet-class>
my_stuff.MyClass
</servlet-class>
场景3.2:
您输入了错误的“ 包装”声明 在myClass.java文件的顶部。
例如:
文件位于:“ / my_stuff ”文件夹中
您错误地写:
package com.my_stuff
这很棘手,因为:
1:Maven版本(mvn软件包)在这里不会报告任何错误。
2:web.xml中的servlet类行可以具有正确的包路径。例如:
<servlet-class>
my_stuff.MyClass
</servlet-class>
使用的堆栈: 记事本++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :
答案 2 :(得分:1)
检查是否输入了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>
此代码段的作用是<url-pattern>/theController</url-pattern>
将设置用于通过URL从前端(例如:表单)调用servlet的名称。因此,当您在前端引用servlet时,为了确保请求到达servlet“ ControllerA”,它应从表单中引用指定的URL模式“ theController”。
例如:
<form action="theController" method="POST">
</form>
答案 3 :(得分:0)
首先,以管理员身份运行IDE。之后,右键单击项目文件夹-> Project Facets,并确保Java版本设置正确。在我的电脑上。 (对于示例1.8)现在应该可以工作了。
不仅使用cmd启动服务器,例如Wildfly。它必须在IDE中启动,现在访问您的本地主机URL。示例:http://localhost:8080/HelloWorldServlet/HelloWorld
答案 4 :(得分:0)
答案 5 :(得分:0)
我也遇到了这个问题,当我访问一个链接到Servlet的URL模式时,我收到了404。原因是因为我有2个Servlet,它们的@WebServlet name
参数设置为相同的字符串。
@WebServlet(name = "ServletName", urlPatterns = {"/path"})
public class ServletName extends HttpServlet {}
@WebServlet(name = "ServletName", urlPatterns = {"/other-path"})
public class OtherServletName extends HttpServlet {}
name
的两个参数都相同。如果您使用的是name参数,请确保它们与应用程序上的所有其他Servlet相比是唯一的。
答案 6 :(得分:0)
如果您是学生并且是Java的新手,那么您的web.xml文件可能会出现一些问题。
- 尝试删除web.xml文件。
- 第二次检查您的路径变量是否正确设置。
- 重新启动tomcat服务器或您的PC。
您的问题一定会得到解决。
答案 7 :(得分:0)
如果有人在这里使用MySQL,并且认为该代码在前一天可以正常工作,而现在却无法正常工作,那么我猜您必须打开MySQL CLI或MySQL Workbench并仅建立一次数据库连接。一旦连接,数据库也将连接到Java应用程序。我曾经遇到过Hibernate Dialect错误,指出com.mysql.jdbc.Driver有问题。我认为某些计算机上的MySQL存在启动问题。这为我解决了。
答案 8 :(得分:0)
我已经完成了在web.xml中的映射:-
packagename.filename,介于打开和关闭xml文件中的servlet-class标记之间。
这两种方法无法相互配合,因此我要么使用创建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>
如果在xml中完成映射,则对相应文件中的代码注释行进行注释。
//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")
答案 9 :(得分:0)
如果您想在不使用“表单”和“提交”按钮的情况下使用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)button-id:您在html / jsp文件中为按钮赋予的'id'标签。
2)full-servlet-path:单独运行servlet时浏览器中显示的路径
答案 10 :(得分:0)
对我有用的修复方法是(如果使用的是Maven):右键单击您的项目,Maven->更新项目。这可能会给您JDK和其他库(在我的情况下为MySQL连接器)带来其他错误,但是一旦修复它们,您的原始问题就应该得到解决!
答案 11 :(得分:0)
一个旧线程,但是由于我没有在其他地方找到它,因此还有另一种可能性:
如果您使用的是 servlet-api 3.0 + ,则您的web.xml必须不包含metadata-complete="true"
属性
这告诉tomcat使用web.xml
中给出的数据而不是使用@WebServlet
注释来映射servlet。
答案 12 :(得分:0)
我删除了旧的Web库,例如spring框架库。并建立图书馆的新路径。然后就可以了。
答案 13 :(得分:0)
执行以下两个步骤。希望能解决Java servlet应用程序开发过程中tomcat服务器中“ 404 not found”的问题。
步骤1:main()
第2步:Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server
答案 14 :(得分:0)
我的问题是我的方法缺少@RequestBody批注。添加注释后,我不再收到404异常。
答案 15 :(得分:0)
在NetBeans IDE中HTTP Status 404
的解决方案:
右键单击项目,然后转到项目属性,然后单击运行,然后输入项目相对URL,例如index.jsp
。
答案 16 :(得分:-1)
请检查上下文根不能为空。
如果您使用的是日食:
右键单击,选择属性,然后选择网络项目设置。选中上下文根不能为空