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/resources
fü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 /jsps
Unterordner 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 @WebServlet
Annotationswert 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 @WebServlet
müssen Sie nur sicherstellen, dass Ihre web.xml
Datei, 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 @WebServlet
Anmerkung.
package com.example;
public class YourServlet extends HttpServlet {
// ...
}
Und registrieren Sie das Servlet stattdessen web.xml
wie 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/classes
Ordner der erstellten WAR-Datei befindet. Im Falle von package com.example; public class YourServlet
muss es sich in befinden /WEB-INF/classes/com/example/YourServlet.class
. Andernfalls werden Sie auch im Falle @WebServlet
eines 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/classes
oder 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:8080
wird 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 /servlet
verfü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:
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
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:
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 :
Datei: PRJ_ROOT / src / main / webapp / WEB-INF / web.xml
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:
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:
Verwendeter Stapel: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :
quelle
Lösung für
HTTP Status 404
in 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 einindex.jsp
.quelle
Mein Problem war, dass meiner Methode die Annotation @RequestBody fehlte. Nach dem Hinzufügen der Anmerkung habe ich die 404-Ausnahme nicht mehr erhalten.
quelle
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
quelle
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.
quelle
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"
AttributDadurch wird Tomcat angewiesen, die Servlets anhand der angegebenen Daten zuzuordnen,
web.xml
anstatt die@WebServlet
Anmerkung zu verwenden.quelle
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
quelle
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!
quelle
Wenn Sie ein Servlet mit Javascript öffnen möchten, ohne die Schaltflächen "Formular" und "Senden" zu verwenden, finden Sie hier den folgenden Code:
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
quelle
Mapping in web.xml ist das, was ich getan habe: -
packagename.filename zwischen dem Öffnen und Schließen des Servlet-Klassen-Tags in der XML-Datei.
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:
Kommentieren Sie die Annotationscodezeile in der jeweiligen Datei, wenn die Zuordnung in XML erfolgt.
quelle
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
quelle