pon*_*ead 82 html forms jsp servlets http-status-code-404
我的文件WebContent/jsps夹中的JSP文件中有一个HTML表单.我servlet.java在src文件夹中的默认包中有一个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
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中,但我只是从您的问题中接管这个.
url-patternservlet 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 /项目配置默认值.
只要服务器运行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错误的问题中也是完全没有意义的.
一旦您确认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>在这里):
表单操作提交到带有前导斜杠的URL.
<form action="/servlet">
Run Code Online (Sandbox Code Playgroud)
前导斜杠/使URL相对于域,因此表单将提交到
http://localhost:8080/servlet
Run Code Online (Sandbox Code Playgroud)
但这可能会导致404,因为它处于错误的上下文中.
表单操作提交到没有前导斜杠的URL.
<form action="servlet">
Run Code Online (Sandbox Code Playgroud)
这使得URL相对于当前URL的当前文件夹,因此表单将提交给
http://localhost:8080/contextname/jsps/servlet
Run Code Online (Sandbox Code Playgroud)
但这可能会导致404,因为它在错误的文件夹中.
表单操作提交到一个文件夹的URL.
<form action="../servlet">
Run Code Online (Sandbox Code Playgroud)
这将是一个文件夹(完全像在本地磁盘文件系统路径!),因此表单将提交
http://localhost:8080/contextname/servlet
Run Code Online (Sandbox Code Playgroud)
这个必须工作!
然而,规范方法是使URL相对于域,这样当您将JSP文件移动到另一个文件夹时,您不需要再次修复URL.
<form action="${pageContext.request.contextPath}/servlet">
Run Code Online (Sandbox Code Playgroud)
这将产生
<form action="/contextname/servlet">
Run Code Online (Sandbox Code Playgroud)
因此,它将始终提交到正确的URL.
你需要确保你在HTML属性中使用直接引号,action="..."或者action='...'因此不是像action=”...”或那样的卷曲引号action=’...’.HTML中不支持卷曲引号,它们只会成为值的一部分.
场景 #1:当 tomcat已经运行时,您意外地从命令行重新部署。
\n\n简短回答:停止 Tomcat,删除目标文件夹、mvn 包,然后重新部署
\n\n场景 #2: request.getRequestDispatcher(" MIS_SPELLED_FILE_NAME .jsp")
\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\n1:停止Tomcat
\n\n2: 删除“target”文件夹。\n (mvn clean 在这里不会帮助你)
\n\n3:mvn包
\n\n4:您的部署命令在这里
\n\n(我的: java -jar target/dependency/webapp-runner.jar --port 5190 target/*.war )
\n\n完整的背景故事:
\n\n不小心打开了一个新的 git-bash 窗口并尝试通过以下方式为我的 heroku 项目部署 .war 文件:
\n\njava -jar 目标/依赖/webapp-runner.jar --端口 5190 目标/*.war
\n\n部署失败后,我意识到我打开了两个 git-bash 窗口,并且没有使用 CTLR+C 来停止之前的部署。
\n\n我遇到了:
\n\n\n\n\nHTTP 状态 404 \xe2\x80\x93 未找到类型状态报告
\n\n消息/if-student-test.jsp
\n\n说明 源服务器未找到目标资源的当前表示\n 或不愿意透露该表示\n 的存在。
\n\n阿帕奇 Tomcat/8.5.31
\n
场景 3.1:\n web.xml 文件中的 servlet 类包路径错误。
\n\n它应该与 java servlet 类顶部的 package 语句匹配。
\n\n文件:my_stuff/ MyClass.java:
\n\n package my_stuff;\nRun 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>\nRun Code Online (Sandbox Code Playgroud)\n\n场景 3.2:
\n\n您在 myClass.java 文件顶部放置了错误的“ package ”语句\n。
\n\n例如:
\n\n文件位于:“ /my_stuff ”文件夹中
\n\n你错误地写了:
\n\npackage com.my_stuff\nRun Code Online (Sandbox Code Playgroud)\n\n这很棘手,因为:
\n\n1:maven构建(mvn包)这里不会报任何错误。
\n\n2:web.xml 中的 servlet-class 行可以有正确的包路径。例如:
\n\n<servlet-class>\nmy_stuff.MyClass\n</servlet-class>\nRun Code Online (Sandbox Code Playgroud)\n\n使用的堆栈:\n Notepad++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :
\n| 归档时间: |
|
| 查看次数: |
99959 次 |
| 最近记录: |