wake-up-neo.com

Servlet gibt "HTTP Status 404 Die angeforderte Ressource (/ servlet) ist nicht verfügbar"

Ich habe ein HTML-Formular in einer JSP-Datei in meinem WebContent/jsps-Ordner. Ich habe eine Servlet-Klasse servlet.Java in meinem Standardpaket im src-Ordner. In meinem web.xml ist es als /servlet zugeordnet.

Ich habe mehrere URLs im action-Attribut des HTML-Formulars ausprobiert:

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

Aber keine dieser Arbeiten. In Tomcat 6/7/8 wird immer wieder ein HTTP 404-Fehler zurückgegeben:

HTTP-Status 404 -/Servlet

Beschreibung : Die angeforderte Ressource (/ Servlet) ist nicht verfügbar.

Oder wie unten in Tomcat 8.5/9:

HTTP-Status 404 - nicht gefunden

Nachricht :/Servlet

Beschreibung : Der Origin-Server hat keine aktuelle Repräsentation für die Zielressource gefunden oder ist nicht bereit, die vorhandene Ressource anzugeben

Warum funktioniert es nicht? 

70
pongahead

Setzen Sie die Servlet-Klasse in ein package

Setzen Sie zunächst die Servlet-Klasse in ein Java package. Sie sollten immer öffentlich wiederverwendbare Java Klassen in ein Paket einfügen, andernfalls sind sie für Klassen, die sich in einem Paket befinden, wie z. B. den Server selbst, unsichtbar. Auf diese Weise beseitigen Sie potenzielle umgebungsspezifische Probleme. Paketlose Servlets funktionieren nur in bestimmten Tomcat + JDK-Kombinationen, auf die Sie sich niemals verlassen sollten.

Im Falle eines "einfachen" IDE Projekts muss die Klasse in ihrer Paketstruktur im Ordner "Java Resources" abgelegt werden und somit nicht ​​"WebContent", dies ist für das Web Dateien wie JSP. Nachfolgend finden Sie ein Beispiel für die Ordnerstruktur einer Standard-Eclipse-Ansicht Dynamisches Webprojekt ​​aus der Sicht Navigator:

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

Im Falle eines Maven-Projekts muss die Klasse in ihrer Paketstruktur innerhalb von main/Javaplatziert werden und somit nicht ​​z. main/resources, dies ist für Dateien ohne Klasse . Unten sehen Sie ein Beispiel für die Ordnerstruktur eines Standard-Maven-Webapp-Projekts in der Eclipse-Ansicht Navigator:

MavenProjectName
 |-- src
 |    `-- main
 |         |-- Java
 |         |    `-- com
 |         |         `-- example
 |         |              `-- YourServlet.Java
 |         |-- resources
 |         `-- webapp
 |              |-- WEB-INF
 |              |    `-- web.xml
 |              `-- jsps
 |                   `-- page.jsp
 :

Beachten Sie, dass der Unterordner /jsps nicht unbedingt erforderlich ist. Sie können sogar darauf verzichten und die JSP-Datei direkt in webcontent/webapp root ablegen, aber ich übernehme dies nur von Ihrer Frage.

Festlegen der Servlet-URL in url-pattern

Die Servlet-URL wird als "URL-Muster" der Servlet-Zuordnung angegeben. Es ist absolut nicht per Definition der Klassenname/Dateiname der Servlet-Klasse. Das URL-Muster muss als Wert von @WebServlet annotation angegeben werden.

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.
    // ...
}

Wenn Sie Pfadparameter wie /servlet/foo/bar unterstützen möchten, verwenden Sie stattdessen das URL-Muster /servlet/*. Siehe auch Servlet- und Pfadparameter wie/xyz/{value}/test, wie in web.xml zuzuordnen?

@WebServlet funktioniert nur mit Servlet 3.0 oder neuer

Um @WebServlet zu verwenden, müssen Sie nur sicherstellen, dass Ihre web.xml -Datei, falls vorhanden (optional seit Servlet 3.0), als konform mit Servlet 3.0+ Version deklariert ist und somit nicht ​​z. 2.5 Version oder niedriger . Nachfolgend finden Sie ein Servlet 3.1-kompatibles Produkt (passend zu Tomcat 8+, WildFly 8+, GlassFish 4+ usw.).

<?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>

Falls Sie noch nicht mit Servlet 3.0+ arbeiten (nicht Tomcat 7 oder neuer, sondern Tomcat 6 oder älter), entfernen Sie die Anmerkung @WebServlet.

package com.example;

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

Und registrieren Sie das Servlet stattdessen wie folgt in 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>

Beachten Sie daher, dass Sie nicht beide Möglichkeiten nutzen sollten. Verwenden Sie entweder eine annotationsbasierte Konfiguration oder eine XML-basierte Konfiguration. Wenn Sie beides haben, überschreibt die XML-basierte Konfiguration die auf Anmerkungen basierende Konfiguration.

Überprüfen des Builds/der Bereitstellung

Wenn Sie ein Build-Tool wie Eclipse und/oder Maven verwenden, müssen Sie unbedingt sicherstellen, dass sich die kompilierte Servlet-Klassendatei in ihrer Paketstruktur im Ordner /WEB-INF/classes der erstellten WAR-Datei befindet. Im Fall von package com.example; public class YourServlet muss es sich in /WEB-INF/classes/com/example/YourServlet.class befinden. Andernfalls wird im Falle von @WebServlet auch ein 404-Fehler oder im Falle von <servlet> ein HTTP 500-Fehler wie der folgende auftreten:

HTTP-Status 500

Fehler beim Instanziieren der Servlet-Klasse com.example.YourServlet

Suchen Sie im Serverprotokoll einen Java.lang.ClassNotFoundException: com.example.YourServlet, gefolgt von einem Java.lang.NoClassDefFoundError: com.example.YourServlet, gefolgt von javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet.

Eine einfache Möglichkeit, um zu überprüfen, ob das Servlet korrekt kompiliert und in den Klassenpfad gestellt wurde, besteht darin, das Build-Tool eine WAR-Datei erstellen zu lassen (z. B. Rechtsklick auf ein Projekt, Exportieren> WAR-Datei in Eclipse) und anschließend dessen Inhalt mit zu überprüfen ein Zip-Tool. Wenn die Servlet-Klasse in /WEB-INF/classes fehlt, ist das Projekt falsch konfiguriert oder einige IDE-/Projektkonfigurationsstandards wurden versehentlich wiederhergestellt (z. B. Projekt> Automatisch erstellen wurde in Eclipse deaktiviert). Wenn Sie keine Ahnung haben, starten Sie am besten von vorne und berühren Sie keine IDE-/Projektkonfigurationsstandards.

Testen Sie das Servlet einzeln

Vorausgesetzt, der Server wird mit localhost:8080 ausgeführt und die WAR wird erfolgreich in einem Kontextpfad von /contextname bereitgestellt (der standardmäßig den Projektnamen IDE verwendet, Groß- und Kleinschreibung beachten!), Und das Servlet hat seine Initialisierung nicht bestanden (Lesen Sie die Serverprotokolle für alle Deployment-/Servlet-Erfolgs-/Fail-Meldungen und den tatsächlichen Kontextpfad und die Servlet-Zuordnung.) Anschließend ist unter /servlet ein Servlet mit dem URL-Muster http://localhost:8080/contextname/servlet verfügbar.

Sie können es einfach direkt in die Adressleiste des Browsers eingeben, um es individuell zu testen. Wenn die Funktion doGet() ordnungsgemäß überschrieben und implementiert wurde, wird die Ausgabe im Browser angezeigt. Oder wenn Sie keine doGet() haben oder wenn es fälschlicherweise super.doGet() aufruft, wird ein " HTTP 405: HTTP-Methode GET wird von dieser URL nicht unterstützt " - Fehler angezeigt (welcher ist immer noch besser als eine 404, da eine 405 beweist, dass das Servlet selbst tatsächlich gefunden wird).

Das Überschreiben von service() ist eine schlechte Vorgehensweise, es sei denn, Sie erfinden ein MVC-Framework neu - was sehr unwahrscheinlich ist, wenn Sie gerade mit Servlets beginnen und keine Ahnung von dem in der aktuellen Frage beschriebenen Problem haben;) Siehe auch Design Patterns webbasierte Anwendungen .

Unabhängig davon, ob das Servlet beim einzelnen Testen bereits 404 zurückgibt, ist es völlig sinnlos, es stattdessen mit einem HTML-Formular zu versuchen. Logischerweise ist es daher auch völlig sinnlos, HTML-Formulare in Fragen zu 404-Fehlern eines Servlets einzubeziehen.

Referenzieren der Servlet-URL aus HTML

Nachdem Sie überprüft haben, ob das Servlet beim Aufrufen einzeln einwandfrei funktioniert, können Sie zu HTML wechseln. Für Ihr konkretes Problem mit dem HTML-Formular muss der Wert <form action> eine gültige URL sein. Gleiches gilt für <a href>. Sie müssen verstehen, wie absolute/relative URLs funktionieren. Sie wissen, dass eine URL eine Webadresse ist, wie Sie in der Adressleiste des Webbrowsers eingeben/sehen können. Wenn Sie eine relative URL als Formularaktion angeben, d. H. Ohne das Schema http://, wird diese relativ zur URL current, wie Sie in der Adressleiste Ihres Webbrowsers sehen. Es ist daher absolut nicht relativ zum Speicherort der JSP/HTML-Datei in der WAR-Ordnerstruktur des Servers, wie viele Starter zu glauben scheinen.

Angenommen, die JSP-Seite mit dem HTML-Formular wird von http://localhost:8080/contextname/jsps/page.jsp geöffnet, und Sie müssen sie an ein Servlet in http://localhost:8080/contextname/servlet senden. In folgenden Fällen können Sie <form action> durch <a href> ersetzen:

  • Die Formularaktion wird an eine URL mit einem führenden Schrägstrich gesendet.

    <form action="/servlet">
    

    Der führende Schrägstrich / macht die URL relativ zur Domain, daher wird das Formular an gesendet

    http://localhost:8080/servlet
    

    Aber dies wird wahrscheinlich zu einem 404 führen, da es im falschen Kontext ist.


  • Die Formularaktion wird an eine URL ohne führenden Schrägstrich gesendet.

    <form action="servlet">
    

    Dadurch wird die URL relativ zum aktuellen Ordner der aktuellen URL erstellt, und das Formular wird an gesendet

    http://localhost:8080/contextname/jsps/servlet
    

    Dies führt jedoch wahrscheinlich zu einem 404, da sich dieser im falschen Ordner befindet.


  • Die Formularaktion wird an eine URL gesendet, die einen Ordner nach oben geht.

    <form action="../servlet">
    

    Dies wird einen Ordner nach oben gehen (genau wie in den Pfaden des lokalen Dateisystems!), Daher wird das Formular an gesendet

    http://localhost:8080/contextname/servlet
    

    Dieser muss funktionieren!


  • Der kanonische Ansatz besteht jedoch darin, die URL domänenbezogen zu machen, damit Sie die URLs nicht erneut korrigieren müssen, wenn Sie die JSP-Dateien in einen anderen Ordner verschieben.

    <form action="${pageContext.request.contextPath}/servlet">
    

    Dies wird erzeugen

    <form action="/contextname/servlet">
    

    Welches wird also immer an die richtige URL übermitteln.


Verwenden Sie einfache Anführungszeichen in HTML

Sie müssen unbedingt sicherstellen, dass Sie gerade Anführungszeichen in HTML-Attributen wie action="..." oder action='...' verwenden und daher nicht ​​geschweifte Anführungszeichen wie action=”...” oder action=’...’. Geschweifte Anführungszeichen werden in HTML nicht unterstützt und werden einfach Teil des Werts.

Siehe auch:

Andere Fälle des HTTP-Status 404-Fehlers:

112
BalusC

Szenario 1: Sie haben versehentlich erneut von der Befehlszeile aus implementiert, während Tomcat bereits ausgeführt hat.

Kurze Antwort: Stoppen Sie Tomcat, Zielordner löschen, mvn-Paket und stellen Sie es anschließend erneut bereit


Szenario # 2: request.getRequestDispatcher ("MIS_SPELLED_FILE_NAME .jsp")

Kurze Antwort: Dateiname überprüfen Schreibweise, sicherstellen, dass case korrekt ist.


Szenario # 3: Klasse nicht gefunden Ausnahmen (Beantworten Sie bitte hier, da: Frage Nr. 17982240) ( Java.lang.ClassNotFoundException für Servlet in Tomcat mit Eclipse ) (War als Duplikat markiert und hierher verwiesen)

Kurze Antwort # 3.1: web.xml hat einen falschen Paketpfad im Tag der Servlet-Klasse.

Kurze Antwort # 3.2: Java-Datei hat falsche Importanweisung.


Nachfolgend finden Sie weitere Details zu Szenario 1:


1: Stoppen Sie Tomcat

  • Option 1: Über STRG + C im Terminal.
  • Option 2: (Terminal geschlossen, während Tomcat noch läuft)
  • ------------ 2.1: drücken Sie: Windows + R -> geben Sie ein: "services.msc"
  • ------------ 2.2: Suchen Sie "Apache Tomcat #. # Tomcat #" in der Spalte "Name" der Liste.
  • ------------ 2.3: Rechtsklick -> "stop"

2: Löschen Sie den "Zielordner" .(mvn clean wird Ihnen hier nicht weiterhelfen)

3: MVN-Paket

4: YOUR_DEPLOYMENT_COMMAND_HERE

(Meine: Java-Ziel/Abhängigkeit/webapp-runner.jar --port 5190-Ziel/*. War)

Vollständige Hintergrundgeschichte:


Versehentlich öffnete ich ein neues git-bash-Fenster und __. Versuchte, eine .war-Datei für mein heroku-Projekt bereitzustellen:

Java-Ziel/Abhängigkeit/webapp-runner.jar --port 5190-Ziel/*

Nachdem die Bereitstellung fehlgeschlagen war, wurde mir klar, dass zwei git-bash-Fenster geöffnet waren. _ Und hatten CTLR + C nicht verwendet, um die vorherige Bereitstellung zu stoppen.

Ich wurde getroffen mit:

HTTP-Status 404 - Statusstatusbericht nicht gefunden

Nachricht /if-student-test.jsp

Beschreibung Der Origin-Server hat keine aktuelle Darstellung gefunden für die Zielressource oder ist nicht bereit, diese zu offenbaren existiert.

Apache Tomcat/8.5.31

Nachfolgend finden Sie weitere Details zu Szenario 3:


SZENARIO 3.1: Der Paketpfad der Servlet-Klasse ist falsch in Ihrer web.xml-Datei.

Es sollte die Package-Anweisung oben abgleichen Ihrer Java-Servlet-Klasse.

Datei: my_stuff/MyClass.Java:

   package my_stuff;

Datei: PRJ_ROOT/src/main/webapp/WEB-INF/web.xml

   <servlet-class>
   my_stuff.MyClass
   </servlet-class>

SZENARIO 3.2:

Sie haben die falsche Anweisung "package" eingegeben oben in Ihrer myClass.Java-Datei.

Zum Beispiel:

Die Datei befindet sich im Ordner "/ my_stuff"

Sie schreiben fälschlicherweise:

package com.my_stuff

Das ist schwierig, weil:

1: Der maven build (mvn package) meldet hier keine Fehler.

2: Die Zeile der Servlet-Klasse in web.xml kann den Pfad des CORRECT-Pakets haben. Z.B:

<servlet-class>
my_stuff.MyClass
</servlet-class>

Verwendeter Stapel: Notepad ++ + GitBash + Maven + Heroku-Webanwendungsläufer + Tomcat9 + Windows10:

1
J.M.I. MADISON

Lösung für HTTP Status 404 in der NetBeans-IDE: Klicken Sie mit der rechten Maustaste auf Ihr Projekt, wechseln Sie zu den Projekteigenschaften, klicken Sie auf Ausführen und geben Sie die relative Projekt-URL wie index.jsp ein.

  1. Projekt-> Eigenschaften
  2. Klicken Sie auf Ausführen
  3. Relative URL: /index.jsp (Wählen Sie die Stamm-URL Ihres Projekts aus.)

enter image description here

0
O R Imon

Mein Problem war, dass bei meiner Methode die @RequestBody-Anmerkung fehlte. Nach dem Hinzufügen der Anmerkung erhielt ich die 404-Ausnahme nicht mehr.

0
THE_DOM

Ein alter Thread, aber da ich ihn woanders nicht gefunden habe, gibt es noch eine Möglichkeit:

Wenn Sie servlet-api 3.0 + verwenden, muss Ihre web.xml NICHT include metadata-complete="true" Attribut

enter image description here

Dadurch wird Tomcat angewiesen, die Servlets anhand der in web.xml angegebenen Daten zuzuordnen, anstatt die Annotation @WebServlet zu verwenden.

0

Führen Sie die folgenden zwei Schritte aus. Ich hoffe, dass das Problem "404 nicht gefunden" auf dem Tomcat-Server während der Entwicklung der Java-Servlet-Anwendung behoben wird.

Schritt 1: Right click on the server(in the server Explorer tab)->Properties->Switch Location from workspace metadata to Tomcat server

Schritt 2: Double Click on the server(in the server Explorer tab)->Select Use Tomcat installation option inside server location menu

0
Sajal Saha

Ich habe die alte Webbibliothek entfernt, bei der es sich um Spring Framework-Bibliotheken handelt. Und baue einen neuen Pfad der Bibliotheken. Dann klappt es.

0
pajarnas