Servlet gibt "HTTP-Status 404 Die angeforderte Ressource (/ Servlet) ist nicht verfügbar" zurück.


91

Ich habe ein HTML-Formular in einer JSP-Datei in meinem WebContent/jspsOrdner. Ich habe eine Servlet-Klasse servlet.javain meinem Standardpaket im srcOrdner. In meinem ist web.xmles als abgebildet /servlet.

Ich habe mehrere URLs im actionAttribut des HTML-Formulars ausprobiert :

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

Aber keine davon funktioniert. Sie alle geben immer wieder einen HTTP 404-Fehler wie unten in Tomcat 6/7/8 zurück:

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 Ursprungsserver hat keine aktuelle Darstellung für die Zielressource gefunden oder ist nicht bereit, diese anzugeben

Warum funktioniert es nicht?

Antworten:


125

Setzen Sie die Servlet-Klasse in a package

Stellen Sie zunächst die Servlet-Klasse in Java package. Sie sollten immer öffentlich wiederverwendbare Java - Klassen in einem Paket geschnürt, da sie sich auf Klassen unsichtbar sind , die in einem Paket sind, wie zum Beispiel des Server selbst. Auf diese Weise beseitigen Sie potenzielle umgebungsspezifische Probleme. Packletlose Servlets funktionieren nur in bestimmten Tomcat + JDK-Kombinationen, auf die man sich niemals verlassen sollte.

Bei einem "einfachen" IDE-Projekt muss die Klasse in ihrer Paketstruktur im Ordner "Java Resources" und nicht in "WebContent" abgelegt werden. Dies gilt für Webdateien wie JSP. Unten finden Sie ein Beispiel für die Ordnerstruktur eines Standard-Eclipse Dynamic-Webprojekts in der Navigatoransicht :

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 platziert werden main/java und ist daher nicht z. B. main/resourcesfür Dateien außerhalb der Klasse . Unten finden Sie ein Beispiel für die Ordnerstruktur eines Standard-Maven-Webanwendungsprojekts in der Navigatoransicht von Eclipse :

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

Beachten Sie, dass der /jspsUnterordner 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.

Legen Sie die Servlet-URL fest 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 ist als @WebServletAnnotationswert anzugeben .

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 unterstützen möchten /servlet/foo/bar, verwenden Sie /servlet/*stattdessen ein URL-Muster von . Siehe auch Servlet- und Pfadparameter wie / xyz / {value} / test, wie in web.xml zuordnen?

@WebServlet funktioniert nur unter Servlet 3.0 oder neuer

Zur Verwendung @WebServletmüssen Sie nur sicherstellen, dass Ihre web.xmlDatei, falls vorhanden (optional seit Servlet 3.0), als konform für Servlet 3.0+ deklariert und daher nicht konform ist, z. B. Version 2.5 oder niedriger . Unten finden Sie eine Servlet 4.0-kompatible Version (die mit Tomcat 9+, WildFly 11+, Payara 5+ usw. übereinstimmt).

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

Falls Sie Servlet 3.0+ noch nicht verwenden (z. B. Tomcat 6 oder älter), entfernen Sie die @WebServletAnmerkung.

package com.example;

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

Und registrieren Sie das Servlet stattdessen web.xmlwie folgt:

<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 verwenden sollten. Verwenden Sie entweder eine annotationsbasierte Konfiguration oder eine XML-basierte Konfiguration. Wenn Sie beide 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 /WEB-INF/classesOrdner der erstellten WAR-Datei befindet. Im Falle von package com.example; public class YourServletmuss es sich in befinden /WEB-INF/classes/com/example/YourServlet.class. Andernfalls werden Sie auch im Falle @WebServleteines 404-Fehlers oder im Falle <servlet>eines HTTP 500-Fehlers wie unten konfrontiert :

HTTP-Status 500

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

Und finden Sie im Serverprotokoll a java.lang.ClassNotFoundException: com.example.YourServlet, gefolgt von a 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 im Klassenpfad platziert wurde, besteht darin, das Build-Tool eine WAR-Datei erstellen zu lassen (z. B. Rechtsklick-Projekt, Exportieren> WAR-Datei in Eclipse) und den Inhalt dann mit einem ZIP-Tool zu überprüfen. Wenn die Servlet-Klasse in fehlt /WEB-INF/classesoder der Export einen Fehler verursacht, ist das Projekt schlecht konfiguriert oder einige Standardeinstellungen für die IDE- / Projektkonfiguration wurden fälschlicherweise zurückgesetzt (z. B. Projekt> Automatisch erstellen wurde in Eclipse deaktiviert).

Sie müssen auch sicherstellen, dass das Projektsymbol kein rotes Kreuz aufweist, das auf einen Erstellungsfehler hinweist. Den genauen Fehler finden Sie in der Problemansicht ( Fenster> Ansicht anzeigen > Andere ... ). Normalerweise ist die Fehlermeldung in Ordnung Googlable. Wenn Sie keine Ahnung haben, starten Sie am besten von vorne und berühren Sie keine Standardeinstellungen für die IDE- / Projektkonfiguration. Falls Sie Eclipse verwenden, finden Sie Anweisungen unter Wie importiere ich die javax.servlet-API in mein Eclipse-Projekt?

Servlet einzeln testen

Vorausgesetzt, der Server localhost:8080wird ausgeführt und die WAR wird erfolgreich in einem Kontextpfad von /contextname(der standardmäßig den IDE-Projektnamen verwendet, Groß- und Kleinschreibung beachten!) Bereitgestellt , und das Servlet hat seine Initialisierung nicht fehlgeschlagen (Serverprotokolle für Bereitstellungen lesen /). Servlet-Erfolgs- / Fehlermeldungen und der tatsächliche Kontextpfad und die Servlet-Zuordnung), dann ist ein Servlet mit dem URL-Muster von /servletverfügbar http://localhost:8080/contextname/servlet.

Sie können es einfach direkt in die Adressleiste des Browsers eingeben, um es einzeln zu testen. Wenn doGet()es richtig überschrieben und implementiert ist, sehen Sie seine Ausgabe im Browser. Wenn Sie keine haben doGet()oder diese falsch aufrufen super.doGet(), wird der Fehler " HTTP 405: HTTP-Methode GET wird von dieser URL nicht unterstützt " angezeigt (der immer noch besser als eine 404 ist, da eine 405 ein Beweis dafür ist, dass das Servlet vorhanden ist selbst wird tatsächlich gefunden).

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

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

Verweisen auf die Servlet-URL aus HTML

Sobald Sie überprüft haben, dass das Servlet beim einzelnen Aufruf einwandfrei funktioniert, können Sie mit HTML fortfahren. In Bezug auf Ihr konkretes Problem mit dem HTML-Formular muss der <form action>Wert eine gültige URL sein. Gleiches gilt für <a href>. Sie müssen verstehen, wie absolute / relative URLs funktionieren. Sie wissen, eine URL ist eine Webadresse, die Sie in der Adressleiste des Webbrowsers eingeben / sehen können. Wenn Sie eine relative URL als Formularaktion angeben, dh ohne das http://Schema, wird sie relativ zur aktuellen URL, 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 denken scheinen.

Also, vorausgesetzt , dass die JSP - Seite mit dem HTML - Formular von geöffnet wird http://localhost:8080/contextname/jsps/page.jsp, und Sie müssen ein Servlet in zu unterwerfen http://localhost:8080/contextname/servlet, sind hier mehrere Fälle (beachten Sie, dass Sie sicher ersetzen können <form action>mit <a href>hier):

  • 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

    Dies wird jedoch wahrscheinlich zu einem 404 führen, da er sich im falschen Kontext befindet.


  • 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, sodass das Formular an gesendet wird

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

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


  • Die Formularaktion wird an eine URL gesendet, die einen Ordner höher liegt.

    <form action="../servlet">

    Dadurch wird ein Ordner nach oben verschoben (genau wie in den lokalen Dateisystempfaden!), 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, sodass 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 senden.


Verwenden Sie in HTML gerade Anführungszeichen

Sie müssen unbedingt sicherstellen, dass Sie in HTML-Attributen wie action="..."oder gerade Anführungszeichen verwenden action='...'und daher keine geschweiften 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 von HTTP-Status 404-Fehler:


web-app version = "3.1" Mit glassfish konnte ich mein Servlet einzeln testen, wenn ich eine Zuordnung in web.xml UND die Anmerkung hatte. Ich habe die Zuordnung entfernt und die Anmerkung hinterlassen, da ich die neueste Version habe, aber dann würde ich einen 404-Fehler erhalten?
SallyRothroat

Dies kann passieren, wenn Sie Servlet 2.5 oder ältere Bibliotheken in die Webanwendung selbst aufnehmen, anstatt sich auf die Ziellaufzeit zu verlassen, um die Servlet-Bibliotheken selbst bereitzustellen.
BalusC

@xdola: Es ist in der Tat spröde, weil es von der Anforderungs-URI abhängt. Lesen Sie einfach die Antwort, um eine Erklärung zu Ihrem Problem und den richtigen Ansatz zu erhalten.
BalusC

4

Szenario 1: Sie wurden versehentlich über die Befehlszeile erneut bereitgestellt , während Tomcat bereits ausgeführt wurde .

Kurze Antwort: Stoppen Sie Tomcat, löschen Sie den Zielordner , das MVN-Paket und stellen Sie es erneut bereit


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

Kurze Antwort: Überprüfen Sie die Schreibweise des Dateinamens und stellen Sie sicher, dass die Groß- und Kleinschreibung korrekt ist.


Szenario 3: Klassen nicht gefundene Ausnahmen (Antwort hier gestellt, weil: Frage Nr. 17982240) ( java.lang.ClassNotFoundException für Servlet in Tomcat mit Eclipse ) (wurde als Duplikat markiert und hat mich hierher geleitet)

Kurze Antwort Nr. 3.1: web.xml hat einen falschen Paketpfad im Servlet-Klassen-Tag.

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 -> Typ: " services.msc "
  • ------------ 2.2: Suchen Sie "Apache Tomcat #. # Tomcat #" in der Spalte "Name" der Liste.
  • ------------ 2.3: Rechtsklick -> " Stopp "

2: Löschen Sie den Ordner "Ziel". (mvn clean hilft dir hier nicht)

3: MVN-Paket

4: YOUR_DEPLOYMENT_COMMAND_HERE

(Meins: java -jar target / dependency / webapp-running.jar --port 5190 target / *. War)

Vollständige Hintergrundgeschichte:


Öffnete versehentlich ein neues Git-Bash-Fenster und versuchte, eine .war-Datei für mein Heroku-Projekt bereitzustellen über:

java -jar target / dependency / webapp-running.jar --port 5190 target / *. war

Nachdem die Bereitstellung fehlgeschlagen war, stellte ich fest, dass zwei Git-Bash-Fenster geöffnet waren und CTLR + C nicht verwendet wurde, um die vorherige Bereitstellung zu stoppen .

Ich wurde getroffen mit:

HTTP-Status 404 - Typstatusbericht nicht gefunden

Nachricht /if-student-test.jsp

Beschreibung Der Ursprungsserver hat keine aktuelle Darstellung für die Zielressource gefunden oder ist nicht bereit, diese anzugeben.

Apache Tomcat / 8.5.31

Nachfolgend finden Sie weitere Details zu Szenario 3:


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

Es sollte mit der Paketanweisung oben in Ihrer Java-Servlet-Klasse übereinstimmen.

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 " package " -Anweisung oben in Ihre myClass.java-Datei eingefügt.

Beispielsweise:

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-Paket) meldet hier keine Fehler.

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

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

Verwendeter Stapel: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :


Ihr AppName.war und damit der explodierte Ordnername stimmen nicht mit Ihrem erwarteten Namen überein, z. B. wenn Ihre War-Datei wie AppName-1.0-SNAPSHOT.war versioniert ist und Sie / AppName / versuchen.
Jla

0

Lösung für HTTP Status 404in NetBeans IDE: Klicken Sie mit der rechten Maustaste auf Ihr Projekt und gehen Sie zu Ihren Projekteigenschaften. Klicken Sie dann auf Ausführen und geben Sie die relative URL Ihres Projekts wie folgt ein index.jsp.

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

Geben Sie hier die Bildbeschreibung ein


0

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


0

Führen Sie die folgenden zwei Schritte aus. Ich hoffe, es wird das Problem "404 nicht gefunden" in Tomcat Server während der Entwicklung der Java-Servlet-Anwendung lösen.

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

Ich habe die alte Webbibliothek entfernt, so dass es sich um Spring Framework-Bibliotheken handelt. Und bauen Sie einen neuen Pfad der Bibliotheken. Dann funktioniert es.


0

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

Wenn Sie mit Servlet-API 3.0 oder höher , dann müssen Sie Ihre web.xml NICHT enthalten metadata-complete="true"Attribut

Geben Sie hier die Bildbeschreibung ein

Dadurch wird Tomcat angewiesen, die Servlets anhand der angegebenen Daten zuzuordnen, web.xmlanstatt die @WebServletAnmerkung zu verwenden.


0

Führen Sie zunächst Ihre IDE als Admin aus. Klicken Sie danach mit der rechten Maustaste auf den Projektordner -> Projektfacetten und stellen Sie sicher, dass die Java-Version korrekt eingestellt ist. Auf meinem PC. (Zum Beispiel 1.8) Jetzt sollte es funktionieren.

Starten Sie Ihren Server, zum Beispiel Wildfly, nicht einfach mit dem Befehl cmd. Es muss in der IDE gestartet werden und jetzt Ihre localhost-URL besuchen. Beispiel: http: // localhost: 8080 / HelloWorldServlet / HelloWorld


0

Das Update, das für mich funktioniert hat, ist (wenn Sie Maven verwenden): Klicken Sie mit der rechten Maustaste auf Ihr Projekt, Maven -> Projekt aktualisieren. Dies kann zu einem anderen Fehler mit dem JDK und anderen Bibliotheken führen (in meinem Fall zum MySQL-Connector), aber sobald Sie diese behoben haben, sollte Ihr ursprüngliches Problem behoben sein!


0

Wenn Sie ein Servlet mit Javascript öffnen möchten, ohne die Schaltflächen "Formular" und "Senden" zu verwenden, finden Sie hier den folgenden Code:

var button = document.getElementById("<<button-id>>");
button.addEventListener("click", function() {
  window.location.href= "<<full-servlet-path>>" (eg. http://localhost:8086/xyz/servlet)
});

Schlüssel:

1) button-id: Das 'id'-Tag, das Sie Ihrem Button in Ihrer HTML / JSP-Datei geben.

2) Full-Servlet-Pfad: Der Pfad, der im Browser angezeigt wird, wenn Sie das Servlet alleine ausführen


0

Mapping in web.xml ist das, was ich getan habe: -

  1. Wenn es ein anderes Paket für ein neues Programm gibt, müssen wir Folgendes erwähnen:

packagename.filename zwischen dem Öffnen und Schließen des Servlet-Klassen-Tags in der XML-Datei.

  1. Wenn Sie Ihre Dateien in XML zuordnen und sie nicht funktionieren oder Fehler anzeigen, kommentieren Sie die Annotationscodezeile in den jeweiligen Dateien.

Beide Methoden funktionieren nicht miteinander. Entweder verwende ich die Annotationsmethode für Dateien, die beim Erstellen eines Servlets erwähnt werden, oder die Art der Zuordnung. Dann lösche oder kommentiere ich die Annotationszeile. Z.B:

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

Kommentieren Sie die Annotationscodezeile in der jeweiligen Datei, wenn die Zuordnung in XML erfolgt.

//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")

-1

Bitte überprüfen Sie, ob der Kontextstamm nicht leer sein darf .

Wenn Sie Eclipse verwenden:
Klicken Sie mit der rechten Maustaste , wählen Sie Eigenschaften und dann die Webprojekteinstellungen aus . Überprüfen Sie, ob der Kontextstamm nicht leer sein darf

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.