Placez la classe de servlet dans un package
Tout d'abord, placez la classe servlet dans un Java package
. Vous devez toujours placer les classes Java réutilisables publiquement dans un package, sinon elles sont invisibles pour les classes qui sont dans un package, comme le serveur lui-même. De cette façon, vous éliminez les problèmes potentiels spécifiques à l'environnement. Les servlets sans paquet ne fonctionnent que dans des combinaisons Tomcat + JDK spécifiques et il ne faut jamais s'y fier.
Dans le cas d'un projet IDE "simple", la classe doit être placée dans sa structure de package dans le dossier "Java Resources" et donc pas "WebContent", c'est pour les fichiers Web tels que JSP. Vous trouverez ci-dessous un exemple de la structure de dossiers d'un projet Web dynamique Eclipse par défaut, comme indiqué dans la vue Navigateur :
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
Dans le cas d'un projet Maven, la classe doit être placée dans sa structure de package à l'intérieur main/java
et donc pas par exemple main/resources
, c'est pour les fichiers non-classe . Vous trouverez ci-dessous un exemple de la structure de dossiers d'un projet Webapp Maven par défaut, comme illustré dans la vue Navigateur d'Eclipse :
MavenProjectName
|-- src
| `-- main
| |-- java
| | `-- com
| | `-- example
| | `-- YourServlet.java
| |-- resources
| `-- webapp
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
Notez que le /jsps
sous-dossier n'est pas strictement nécessaire. Vous pouvez même vous en passer et placer le fichier JSP directement dans la racine webcontent / webapp, mais je reprends simplement cela à partir de votre question.
Définir l'URL du servlet dans url-pattern
L'URL du servlet est spécifiée comme "modèle d'URL" du mappage de servlet. Ce n'est absolument pas par définition le nom de classe / nom de fichier de la classe de servlet. Le modèle d'URL doit être spécifié comme valeur d' @WebServlet
annotation.
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.
// ...
}
Si vous souhaitez prendre en charge des paramètres de chemin tels que /servlet/foo/bar
, utilisez /servlet/*
plutôt un modèle d'URL . Voir aussi Servlet et paramètres de chemin comme / xyz / {value} / test, comment mapper dans web.xml?
@WebServlet
fonctionne uniquement sur Servlet 3.0 ou plus récent
Pour l'utiliser @WebServlet
, vous devez seulement vous assurer que votre web.xml
fichier, le cas échéant (il est facultatif depuis Servlet 3.0), est déclaré conforme à la version Servlet 3.0+ et donc non conforme, par exemple la version 2.5 ou inférieure . Vous trouverez ci-dessous un compatible Servlet 4.0 (qui correspond à Tomcat 9+, WildFly 11+, Payara 5+, etc.).
<?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>
Ou, si vous n'êtes pas encore sur Servlet 3.0+ (par exemple Tomcat 6 ou plus ancien), supprimez l' @WebServlet
annotation.
package com.example;
public class YourServlet extends HttpServlet {
// ...
}
Et enregistrez le servlet à la place web.xml
comme ceci:
<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>
Notez donc que vous ne devez pas utiliser les deux méthodes. Utilisez une configuration basée sur des annotations ou une configuration basée sur XML. Lorsque vous avez les deux, la configuration basée sur XML remplace la configuration basée sur les annotations.
Vérification de la construction / du déploiement
Si vous utilisez un outil de construction tel qu'Eclipse et / ou Maven, vous devez vous assurer absolument que le fichier de classe de servlet compilé réside dans sa structure de package dans le /WEB-INF/classes
dossier du fichier WAR produit. Dans le cas de package com.example; public class YourServlet
, il doit être situé dans /WEB-INF/classes/com/example/YourServlet.class
. Sinon, vous serez confronté en cas d' @WebServlet
erreur 404 ou en cas d' <servlet>
erreur HTTP 500 comme ci-dessous:
État HTTP 500
Erreur lors de l'instanciation de la classe de servlet com.example.YourServlet
Et trouvez dans le journal du serveur a java.lang.ClassNotFoundException: com.example.YourServlet
, suivi de a java.lang.NoClassDefFoundError: com.example.YourServlet
, à son tour suivi de javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
.
Un moyen simple de vérifier si le servlet est correctement compilé et placé dans classpath est de laisser l'outil de construction produire un fichier WAR (par exemple, cliquez avec le bouton droit sur le projet, Exporter> Fichier WAR dans Eclipse) et ensuite inspecter son contenu avec un outil ZIP. Si la classe de servlet est manquante dans /WEB-INF/classes
, ou si l'exportation provoque une erreur, le projet est mal configuré ou certaines valeurs par défaut de configuration IDE / projet ont été rétablies par erreur (par exemple, Projet> Construire automatiquement a été désactivé dans Eclipse).
Vous devez également vous assurer que l'icône du projet n'a pas de croix rouge indiquant une erreur de construction. Vous pouvez trouver l'erreur exacte dans la vue Problèmes ( Fenêtre> Afficher la vue> Autre ... ). Habituellement, le message d'erreur est bien Googlable. Dans le cas où vous n'avez aucune idée, le mieux est de redémarrer à partir de zéro et de ne pas toucher aux valeurs par défaut de configuration IDE / projet. Si vous utilisez Eclipse, vous pouvez trouver des instructions dans Comment importer l'API javax.servlet dans mon projet Eclipse?
Tester le servlet individuellement
À condition que le serveur s'exécute localhost:8080
et que le WAR soit déployé avec succès sur un chemin de contexte de /contextname
(qui par défaut est le nom du projet IDE, sensible à la casse!), Et que le servlet n'a pas échoué son initialisation (lire les journaux du serveur pour tout déploiement / les messages de réussite / échec du servlet et le chemin de contexte réel et le mappage de servlet), puis un servlet avec un modèle d'URL /servlet
est disponible sur http://localhost:8080/contextname/servlet
.
Vous pouvez simplement le saisir directement dans la barre d'adresse du navigateur pour le tester de manière individuelle. S'il doGet()
est correctement remplacé et implémenté, vous verrez sa sortie dans le navigateur. Ou si vous n'en avez pas doGet()
ou s'il appelle incorrectement super.doGet()
, une erreur " HTTP 405: Méthode HTTP GET n'est pas prise en charge par cette URL " sera affichée (ce qui est toujours mieux qu'un 404 car un 405 est la preuve que le servlet se trouve réellement).
Le remplacement service()
est une mauvaise pratique, à moins que vous ne réinventiez un framework MVC - ce qui est très peu probable si vous débutez avec des servlets et que vous n'avez aucune idée du problème décrit dans la question actuelle;) Voir aussi les applications Web Design Patterns .
Quoi qu'il en soit, si le servlet renvoie déjà 404 lorsqu'il est testé individuellement, il est alors totalement inutile d'essayer avec un formulaire HTML à la place. Logiquement, il est donc également totalement inutile d'inclure un formulaire HTML dans des questions sur les erreurs 404 d'un servlet.
Référencer l'URL du servlet à partir du HTML
Une fois que vous avez vérifié que le servlet fonctionne correctement lorsqu'il est appelé individuellement, vous pouvez passer au HTML. Quant à votre problème concret avec le formulaire HTML, la <form action>
valeur doit être une URL valide. La même chose s'applique à <a href>
. Vous devez comprendre le fonctionnement des URL absolues / relatives. Vous savez, une URL est une adresse Web comme vous pouvez la saisir / la voir dans la barre d'adresse du navigateur Web. Si vous spécifiez une URL relative comme action de formulaire, c'est-à-dire sans le http://
schéma, elle devient relative à l' URL actuelle comme vous le voyez dans la barre d'adresse de votre navigateur Web. Ce n'est donc absolument pas relatif à l'emplacement du fichier JSP / HTML dans la structure des dossiers WAR du serveur comme de nombreux débutants semblent le penser.
Donc, en supposant que la page JSP avec le formulaire HTML est ouverte par http://localhost:8080/contextname/jsps/page.jsp
, et que vous devez vous soumettre à un servlet situé dans http://localhost:8080/contextname/servlet
, voici plusieurs cas (notez que vous pouvez remplacer en toute sécurité <form action>
par <a href>
ici):
L'action de formulaire se soumet à une URL avec une barre oblique en tête.
<form action="/servlet">
La barre oblique principale /
rend l'URL relative au domaine, ainsi le formulaire sera soumis à
http://localhost:8080/servlet
Mais cela entraînera probablement un 404 car il est dans le mauvais contexte.
L'action de formulaire est soumise à une URL sans barre oblique.
<form action="servlet">
Cela rend l'URL relative au dossier actuel de l'URL actuelle, ainsi le formulaire sera soumis à
http://localhost:8080/contextname/jsps/servlet
Mais cela entraînera probablement un 404 car il se trouve dans le mauvais dossier.
L'action de formulaire se soumet à une URL qui monte d'un dossier.
<form action="../servlet">
Cela ira d'un dossier vers le haut (exactement comme dans les chemins du système de fichiers du disque local!), Ainsi le formulaire sera soumis à
http://localhost:8080/contextname/servlet
Celui-ci doit fonctionner!
L'approche canonique, cependant, consiste à rendre l'URL relative au domaine afin que vous n'ayez pas besoin de réparer les URL à nouveau lorsque vous déplacez les fichiers JSP dans un autre dossier.
<form action="${pageContext.request.contextPath}/servlet">
Cela générera
<form action="/contextname/servlet">
Lequel se soumettra donc toujours à la bonne URL.
Utilisez des guillemets droits en HTML
Vous devez absolument vous assurer que vous utilisez des guillemets droits dans les attributs HTML comme action="..."
ou action='...'
et donc pas des guillemets bouclés comme action=”...”
ou action=’...’
. Les guillemets bouclés ne sont pas pris en charge en HTML et feront simplement partie de la valeur.
Voir également:
Autres cas d'erreur HTTP Status 404:
Scénario n ° 1: vous avez accidentellement redéployé à partir de la ligne de commande alors que tomcat était déjà en cours d'exécution .
Réponse courte: arrêtez Tomcat, supprimez le dossier cible , le package mvn, puis redéployez
Scénario n ° 2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME .jsp")
Réponse courte: Vérifiez l' orthographe du nom de fichier , assurez-vous que la casse est correcte.
Scénario n ° 3: Exceptions de classe non trouvée (réponse mise ici car: Question n ° 17982240) ( java.lang.ClassNotFoundException pour servlet dans tomcat avec eclipse ) (a été marqué comme dupliqué et m'a dirigé ici)
Réponse courte n ° 3.1: web.xml a un chemin de package incorrect dans la balise de classe servlet.
Réponse courte n ° 3.2: le fichier java a une mauvaise déclaration d'importation.
Vous trouverez ci-dessous plus de détails pour le scénario n ° 1:
1: Arrêtez Tomcat
2: Supprimez le dossier "cible". (mvn clean ne vous aidera pas ici)
3: paquet mvn
4: VOTRE_DEPLOIEMENT_COMMAND_HERE
(Mine: java -jar target / dependency / webapp-runner.jar --port 5190 target / *. War)
Histoire complète:
J'ai accidentellement ouvert une nouvelle fenêtre git-bash et essayé de déployer un fichier .war pour mon projet heroku via:
java -jar target / dependency / webapp-runner.jar --port 5190 target / *. war
Après un échec de déploiement, j'ai réalisé que j'avais deux fenêtres git-bash ouvertes et que je n'avais pas utilisé CTLR + C pour arrêter le déploiement précédent .
J'ai été rencontré:
Vous trouverez ci-dessous plus de détails pour le scénario n ° 3:
SCÉNARIO 3.1: Le chemin du package de la classe servlet est incorrect dans votre fichier web.xml.
Il doit correspondre à l'instruction package en haut de votre classe de servlet java.
Fichier: my_stuff / MyClass.java :
Fichier: PRJ_ROOT / src / main / webapp / WEB-INF / web.xml
SCÉNARIO 3.2:
Vous avez mis la mauvaise déclaration " package " en haut de votre fichier myClass.java.
Par exemple:
Le fichier se trouve dans le dossier " / my_stuff "
Vous écrivez par erreur:
C'est délicat car:
1: Le build maven (package mvn) ne rapportera aucune erreur ici.
2: la ligne de classe servlet dans web.xml peut avoir le chemin de package CORRECT. Par exemple:
Pile utilisée: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :
la source
Solution pour
HTTP Status 404
NetBeans IDE: Faites un clic droit sur votre projet et accédez aux propriétés de votre projet, puis cliquez sur Exécuter, puis saisissez l'URL relative de votre projet commeindex.jsp
.la source
Mon problème était que ma méthode manquait l'annotation @RequestBody. Après avoir ajouté l'annotation, je n'ai plus reçu l'exception 404.
la source
Suivez les deux étapes suivantes. J'espère que cela résoudra le problème "404 non trouvé" dans le serveur tomcat pendant le développement de l'application de servlet java.
Étape 1:
Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server
Étape 2:
Double Click on the server(in the server explorer tab)->Select Use tomcat installation option inside server location menu
la source
J'ai supprimé l'ancienne bibliothèque Web telle que les bibliothèques de framework Spring. Et construisez un nouveau chemin des bibliothèques. Alors ça marche.
la source
Un vieux fil, mais comme je ne l'ai pas trouvé ailleurs, voici une autre possibilité:
Si vous utilisez servlet-api 3.0+ , votre web.xml ne doit PAS inclure d'
metadata-complete="true"
attributCela indique à tomcat de mapper les servlets en utilisant les données fournies dans
web.xml
au lieu d'utiliser l'@WebServlet
annotation.la source
Tout d'abord, exécutez votre IDE en tant qu'administrateur. Après cela, cliquez avec le bouton droit sur le dossier du projet -> Facettes du projet et assurez-vous que la version Java est définie correctement. Sur mon PC. (Par exemple 1.8) Maintenant, cela devrait fonctionner.
Ne démarrez pas simplement votre serveur, par exemple Wildfly, en utilisant le cmd. Il doit être lancé dans l'EDI et maintenant visiter votre URL localhost. Exemple: http: // localhost: 8080 / HelloWorldServlet / HelloWorld
la source
Le correctif qui a fonctionné pour moi est (si vous utilisez Maven): Cliquez avec le bouton droit sur votre projet, Maven -> Mettre à jour le projet. Cela pourrait vous donner une autre erreur avec le JDK et d'autres bibliothèques (dans mon cas, le connecteur MySQL), mais une fois que vous les avez résolus, votre problème d'origine devrait être corrigé!
la source
Si vous souhaitez ouvrir un servlet avec javascript sans utiliser les boutons 'formulaire' et 'soumettre', voici le code suivant:
Clé:
1) button-id: La balise 'id' que vous donnez à votre bouton dans votre fichier html / jsp.
2) full-servlet-path: le chemin qui s'affiche dans le navigateur lorsque vous exécutez le servlet seul
la source
La cartographie en web.xml est ce que j'ai fait: -
packagename.filename entre l'ouverture et la fermeture de la balise de classe servlet dans le fichier xml.
Les deux méthodes ne fonctionnent pas l'une avec l'autre, donc j'utilise la méthode d'annotation des fichiers mentionnés lorsque nous créons le servlet ou la méthode de mappage, puis je supprime ou commente la ligne d'annotation. Par exemple:
Commenter la ligne d'annotation du code dans le fichier respectif, si le mappage en xml est effectué.
la source
Veuillez vérifier que la racine du contexte ne peut pas être vide .
Si vous utilisez eclipse: faites
un clic droit , sélectionnez les propriétés , puis les paramètres du projet Web . Vérifiez que la racine de contexte ne peut pas être vide
la source