servlet返回“http状态404请求的资源(/servlet)不可用”

nc1teljy  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(1136)

我的jsp文件中有一个html表单 WebContent/jsps 文件夹。我有一个servlet类 servlet.java 在我的默认包中 src 文件夹。在我的 web.xml 它被Map为 /servlet .
我已经尝试了几个网址 action html表单的属性:

<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
描述:源服务器找不到目标资源的当前表示形式,或者不愿意透露该表示形式的存在
为什么不起作用?

acruukt9

acruukt91#

将servlet类放入包中

首先,将servlet类放在java中 package . 您应该始终将可公开重用的java类放在一个包中,否则它们对于包中的类(例如服务器本身)是不可见的。这样就可以消除潜在的特定于环境的问题。无包servlet只能在特定的tomcat+jdk组合中工作,不应该依赖它。
对于“普通”ide项目,类需要放在“javaresources”文件夹中的包结构中,而不是“webcontent”,这是针对jsp等web文件的。下面是默认eclipse动态web项目的文件夹结构示例,如navigator视图所示:

EclipseProjectName
 |-- src
 |    `-- com
 |         `-- example
 |              `-- YourServlet.java
 |-- WebContent
 |    |-- WEB-INF
 |    |    `-- web.xml
 |    `-- jsps
 |         `-- page.jsp
 :

对于maven项目,类需要放在它的包结构中 main/java 因此不是。 main/resources ,这是针对非类文件的。以下是默认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模式中设置servlet url

servlet url被指定为servletMap的“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和路径参数,如/xyz/{value}/test,how to map in web.xml?

@webservlet仅适用于Servlet3.0或更新版本

为了使用 @WebServlet ,您只需确保 web.xml 如果有文件(由于Servlet3.0是可选的),则声明为符合Servlet3.0+版本,因此不符合例如2.5版本或更低的版本。下面是一个与Servlet4.0兼容的servlet(它匹配Tomcat9+、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>

或者,如果您还没有使用Servlet3.0+(例如Tomcat6或更高版本),则删除 @WebServlet 注解。

package com.example;

public class YourServlet extends HttpServlet {
    // ...
}

并在中注册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>

因此请注意,您不应该同时使用这两种方法。使用基于注解的配置或基于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中右键单击project,export>war文件),然后使用zip工具检查其内容。如果中缺少servlet类 /WEB-INF/classes ,或者如果导出导致错误,则说明项目配置不正确,或者某些ide/项目配置默认值被错误地还原(例如,在eclipse中禁用了project>build automatically)。
您还需要确保项目图标没有表示生成错误的红十字。您可以在“问题”视图(窗口>显示视图>其他…)中找到确切的错误。通常错误消息是很好的google。如果您不知道,最好是从头开始重新启动,不要接触任何ide/项目配置默认值。如果您使用的是eclipse,您可以在如何在eclipse项目中导入javax.servlet api中找到说明?

单独测试servlet

如果服务器运行在 localhost:8080 战争成功地部署在 /contextname (默认为ide项目名称,区分大小写!),并且servlet没有初始化失败(读取服务器日志中的任何deploy/servlet success/fail消息以及实际的上下文路径和servletMap),然后是一个url模式为 /servlet 可在 http://localhost:8080/contextname/servlet .
您只需直接在浏览器的地址栏中输入它就可以进行独立测试。如果是 doGet() 正确地重写和实现,然后您将在浏览器中看到它的输出。或者如果你没有 doGet() 或者如果它不正确地呼叫 super.doGet() ,则会显示“http405:httpmethodget is not supported by this url”错误(这仍然比404好,因为405是实际找到servlet本身的证据)。
覆盖 service() 这是一种糟糕的做法,除非您正在重新创建一个mvc框架——如果您刚开始使用servlet,并且对当前问题中描述的问题一无所知,这是非常不可能的;)另请参见基于web的应用程序的设计模式。
不管怎样,如果servlet在进行独立测试时已经返回404,那么尝试使用html表单完全没有意义。因此,从逻辑上讲,在有关servlet的404错误的问题中包含任何html表单也是完全没有意义的。

从html引用servlet url

一旦您验证了servlet在单独调用时工作正常,那么您就可以进入html了。至于html表单的具体问题 <form action> 值必须是有效的url。这同样适用于 <a href> . 您需要了解绝对/相对URL是如何工作的。你知道,url是一个网址,你可以在webbrowser的地址栏中输入/看到。如果将相对url指定为表单操作,即不使用 http:// 方案,然后它就变成相对于当前url,正如您在webbrowser的地址栏中看到的那样。因此,它绝对不是像许多初学者认为的那样相对于服务器war文件夹结构中的jsp/html文件位置。
因此,假设带有html表单的jsp页面是由 http://localhost:8080/contextname/jsps/page.jsp ,您需要提交到位于 http://localhost:8080/contextname/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=’...’ . curl 引号在html中不受支持,它们只会成为值的一部分。从博客复制粘贴代码片段时要小心!一些博客引擎,尤其是wordpress,默认情况下使用所谓的“智能引号”,这样也会以这种方式破坏代码片段中的引号。另一方面,与其复制粘贴代码,不如自己简单地在代码上键入。通过你的大脑和手指实际获取代码的另一个好处是,从长远来看,它将使你更好地记住和理解代码,也使你成为一个更好的开发人员。

另请参见:

我们的servlets wiki页面-包含一些hello world示例
如何从html表单调用servlet类
servlet中的doget和dopost
如何通过单击jsp页面中的超链接或按钮将当前项传递给java方法?

http状态404错误的其他情况:

http状态404-servlet[servletname]不可用
http状态404-请求的资源(/projectname/)不可用
http状态404-请求的资源(/)不可用
/web inf中的jsp返回“http状态404请求的资源不可用”
在jsp文件中引用放置在webinf文件夹中的资源将返回资源上的http404
当调用一个转发到jsp的servlet时,浏览器不能访问/找到相关的资源,比如css、图像和链接

whitzsjs

whitzsjs2#

场景1:当tomcat已经运行时,您意外地从命令行重新部署。
简单回答:停止tomcat,删除目标文件夹,mvn包,然后重新部署
场景2:request.getrequestdispatcher(“拼写错误的文件名jsp”)
简短回答:检查文件名拼写,确保大小写正确。
场景3:cla

相关问题