Servlet retourne " HTTP Status 404 la ressource demandée (/servlet) n'est pas disponible"

j'ai un formulaire HTML dans un fichier JSP dans mon dossier WebContent/jsps . J'ai une classe de servlet servlet.java dans mon paquet par défaut dans le dossier src . Dans mon web.xml il est cartographié comme /servlet .

j'ai essayé plusieurs URLs dans l'attribut action de la forme HTML:

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

mais ça ne marche pas. Ils continuent tous à renvoyer une erreur HTTP 404 comme ci-dessous dans Tomcat 6/7/8:

HTTP Status 404 - / servlet

Description : la ressource demandée (/servlet) n'est pas disponible.

ou comme ci-dessous dans Tomcat 8.5/9:

HTTP Status 404-Not Found""

Message : / servlet

Description : Le serveur d'origine n'a pas trouvé de représentation actuelle pour la ressource cible ou n'est pas disposé à divulguer qu'il en existe une

pourquoi ça ne marche pas?

61
demandé sur BalusC 2012-07-31 04:02:45

3 réponses

mettre la classe servlet dans un package

tout d'abord, mettez la classe servlet dans un Java package . Vous devriez toujours mettre publiquement des classes Java réutilisables dans un paquet, sinon elles sont invisibles pour les classes qui sont dans un paquet, comme le serveur lui-même. De cette façon, vous éliminez les problèmes environnementaux potentiels. Les servlets Packageless ne fonctionnent que dans des combinaisons Tomcat+JDK spécifiques et ne doivent jamais être utilisés sur.

dans le cas d'un projet IDE" simple", la classe doit être placée dans sa structure de paquet à l'intérieur du dossier" Java Resources "et donc et non " WebContent", c'est pour les fichiers web tels que JSP. Ci-dessous est un exemple de la structure du dossier D'une éclipse par défaut projet web dynamique comme vu dans navigateur vue:

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é dans sa structure de paquet à l'intérieur de main/java et donc et non par exemple main/resources , ceci est pour les fichiers non-Classe . Ci - dessous est un exemple de la structure de dossier d'un projet webapp Maven par défaut comme vu dans Navigator view:

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

notez que le sous-dossier /jsps n'est pas strictement nécessaire. Vous pouvez même vous en passer et mettre le fichier JSP directement dans webcontent / webapp root, mais je ne fais que reprendre cela à votre question.

Définir l'URL du servlet dans url-pattern

l'URL du servlet est spécifiée comme le" motif D'URL " de la cartographie du servlet. Ce n'est absolument pas par définition le nom de classe/nom de fichier de la classe servlet. Le modèle D'URL doit être spécifié comme valeur de @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.
    // ...
}

dans le cas où vous voulez supporter des paramètres de chemin comme /servlet/foo/bar , puis utilisez un modèle D'URL de /servlet/* à la place. Voir aussi Servlet et les paramètres de chemin comme/xyz / {valeur} / test, comment cartographier dans web.xml?

@WebServlet fonctionne seulement sur Servlet 3.0 ou plus récent

pour utiliser @WebServlet , il vous suffit de vous assurer que votre fichier web.xml , s'il y en a un (il est optionnel depuis Servlet 3.0), est déclaré conforme Servlet 3.0+ version et donc pas conforme, p.ex. version 2.5 ou inférieure . Ci-dessous une Servlet 3.1 compatible (qui correspond à Tomcat 8+, WildFly 8+, GlassFish 4+, etc).

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

ou, si vous n'êtes pas encore sur Servlet 3.0+ (pas Tomcat 7 ou plus récent, mais Tomcat 6 ou plus ancien), puis supprimer l'annotation @WebServlet .

package com.example;

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

et enregistrer le servlet à la place dans 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>

Note ainsi, vous ne devriez pas utiliser les deux voies. Utilisez soit la configuration basée sur l'annotation ou la configuration basée sur XML. Lorsque vous avez les deux, alors la configuration basée sur XML supplantera la configuration basée sur les annotations.

vérifier la construction /le déploiement

dans le cas où vous utilisez un outil de construction tel que Eclipse et/ou Maven, alors vous devez vous assurer absolument que le fichier de classe servlet compilé réside dans sa structure de paquet dans le dossier /WEB-INF/classes du dossier de guerre produit. Dans le cas de package com.example; public class YourServlet , il doit être situé dans /WEB-INF/classes/com/example/YourServlet.class . Dans le cas contraire, vous rencontrerez aussi une erreur 404 dans @WebServlet ou une erreur HTTP 500 dans <servlet> comme ci-dessous:

HTTP Status 500

Error instanciating servlet class com.exemple.Votreservlet

et trouver dans le log du serveur un java.lang.ClassNotFoundException: com.example.YourServlet , suivi d'un java.lang.NoClassDefFoundError: com.example.YourServlet , à son tour suivi de javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet .

un moyen facile de vérifier si le servlet est correctement compilé et placé dans classpath est de laisser l'outil de compilation produire un fichier de guerre (par exemple rightclick project, Export > WAR file in Eclipse) et d'inspecter son contenu avec un outil ZIP. Si la classe servlet est manquante dans /WEB-INF/classes , alors le projet est mal configuré ou certaines valeurs par défaut IDE/project ont été inversées par erreur (par exemple Projet > construire automatiquement a été désactivé dans Eclipse). Dans le cas où vous n'avez aucune idée, le mieux est de redémarrer à partir de zéro et ne touchez aucune configuration IDE/projet par défaut.

essai du servlet individuellement

pourvu que le serveur tourne sur localhost:8080 , et que la guerre soit déployée avec succès sur un chemin de contexte de /contextname (par défaut au nom du projet IDE, sensible à la casse!), et le servlet n'a pas échoué son initialisation (lire les journaux du serveur pour tous les messages de réussite/échec de déploiement/servlet et le chemin de contexte réel et servlet mapping), puis un servlet avec le modèle D'URL de /servlet est disponible à http://localhost:8080/contextname/servlet .

vous pouvez simplement l'entrer directement dans la barre d'adresse du navigateur pour le tester invivuellement. Si son doGet() est correctement overriden et mis en œuvre, alors vous verrez sa sortie dans le navigateur. Ou si vous n'avez pas de doGet() ou si elle appelle incorrectement super.doGet() , puis une " HTTP 405: HTTP method GET n'est pas supporté par cette URL " erreur sera affiché (ce qui est toujours mieux qu'un 404 comme un 405 est la preuve que le servlet lui-même est effectivement trouvé).

outrepasser service() est une mauvaise pratique, à moins que vous réinventez un cadre MVC - ce qui est très peu probable si vous venez de commencer avec des servlets et sont ignorants quant au problème décrit dans la question actuelle;) Voir aussi Modèles de Conception des applications web .

quoi qu'il en soit, si le servlet renvoie déjà 404 lorsqu'il est testé invivuellement, alors il est tout à fait inutile d'essayer avec un formulaire HTML à la place. Logiquement, il est donc tout à fait inutile d'inclure n'importe quel format HTML dans les questions sur les erreurs 404 d'un servlet.

référence à L'URL du servlet de HTML

une fois que vous avez vérifié que le servlet fonctionne bien lorsqu'il est invoqué individuellement, alors vous pouvez avancer vers HTML. En ce qui concerne votre problème concret avec la forme HTML, la valeur <form action> doit être une URL valide. Il en va de même pour <a href> . Vous devez comprendre comment les URLs absolues/relatives fonctionnent. Vous savez, une URL est une adresse web que vous pouvez entrer/voir dans la barre d'adresse du webbrowser. Si vous spécifiez une URL relative comme action de forme, c'est-à-dire sans le schéma http:// , alors elle devient relative à L'URL courante comme vous le voyez dans votre barre d'adresse du navigateur. Ce n'est donc absolument pas relatif à l'emplacement du fichier JSP/HTML dans la structure du dossier WAR du serveur comme semblent le penser de nombreux débutants.

donc, en supposant que la page JSP avec le formulaire HTML est ouverte par http://localhost:8080/contextname/jsps/page.jsp , et que vous avez besoin de soumettre à un servlet situé dans http://localhost:8080/contextname/servlet , voici plusieurs cas (notez que vous pouvez sans risque remplacer <form action> par <a href> ici):

  • forme action soumet à une URL avec une barre oblique principale.

    <form action="/servlet">
    

    la barre oblique principale / rend L'URL relative au domaine, ainsi le formulaire se soumettra à

    http://localhost:8080/servlet
    

    mais cela aboutira probablement à un 404 car c'est dans le mauvais contexte.


  • l'action de forme se soumet à une URL sans une barre oblique principale.

    <form action="servlet">
    

    cela rend L'URL relative au dossier courant de L'URL actuelle, ainsi le formulaire se soumettra à

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

    mais il en résultera probablement un 404 car il est dans le mauvais dossier.


  • form action soumet à une URL qui va un dossier vers le haut.

    <form action="../servlet">
    

    cela va monter un dossier (exactement comme dans les chemins du système de fichiers Disque local!), ainsi le formulaire sera soumis à

    http://localhost:8080/contextname/servlet
    

    celui-ci doit marcher!


  • l'approche canonique, cependant, est de rendre le domaine URL-relative de sorte que vous n'avez pas besoin de corriger les URLs une fois de plus quand vous arrive de déplacer les fichiers JSP autour dans un autre dossier.

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

    cela générera

    <form action="/contextname/servlet">
    

    qui sera ainsi toujours soumettre à la bonne URL.


utilisez des guillemets en HTML

vous devez absolument vous assurer que vous utilisez des guillemets droits dans les attributs HTML comme action="..." ou action='...' et donc pas guillemets comme action=”...” ou action=’...’ . Les guillemets ne sont pas pris en charge en HTML et deviendront simplement une partie de la valeur.

Voir aussi:

autres cas D'erreur HTTP Status 404:

97
répondu BalusC 2017-11-13 06:47:31

Solution pour HTTP Status 404 in NetBeans IDE: Cliquez avec le bouton droit de la souris sur votre projet et allez à Propriétés de votre projet, puis cliquez sur run, puis entrez L'URL relative de votre projet comme index.jsp .

  1. Projet - > Propriétés
  2. "151950920 Cliquez sur" Exécuter
  3. Relative URL: / index.jsp (Sélectionnez votre projet racine de l'URL)

enter image description here

0
répondu O R Imon 2018-06-25 11:43:21

scénario 1: vous accidentellement déployé à partir de la ligne de commande alors que tomcat était déjà lancé .

réponse courte: Stop Tomcat, supprimer le dossier cible , paquet mvn, puis re-déployer


scénario 2: demande .getRequestDispatcher (" MIS_SPELLED_FILE_NAME .JSP")

brève réponse: nom du fichier de contrôle orthographe , assurez-vous que case est correcte.


Scénario 3: Classe Non Trouvée Exceptions (Réponse mise ici parce que: Question# 17982240 ) ( de java.lang.ClassNotFoundException de servlet tomcat avec eclipse ) (a été marqué comme dupliquer et m'a dirigé ici )

courte réponse # 3.1: web.xml a le mauvais chemin de paquet dans la balise servlet-class.

brève réponse # 3.2: le fichier java a une fausse déclaration d'importation.


vous trouverez ci-dessous d'autres détails pour le scénario 1:


1: Stop Tomcat

  • Option 1: Via CTRL+C dans le terminal.
  • Option 2: (terminal fermé pendant que tomcat est toujours en cours d'exécution)
  • ------------ 2.1: appuyez sur: Windows+R -- > type:" services.msc "
  • ------------ 2.2: Trouver "Apache Tomcat #.# Tomcat# " dans la colonne des noms de la liste.
  • ------------ 2.3: Clic Droit --> " stop "

2: supprimer le dossier" cible". (mvn clean ne veut pas vous aider ici)

3: paquet mvn

4: YOUR_DEPENDEMENT_COMMAND_HERE

(le Mien: java-jar cible/dépendance/webapp-coureur.jar --port 5190 cible/*.de guerre )

Histoire Complète:


ouvre accidentellement une nouvelle fenêtre git-bash et essayé de déployer un .fichier war pour mon projet heroku via:

java-jar cible/dépendance/webapp-coureur.jar --port 5190 cible/*.de la guerre

après une panne de déploiement, j'ai réalisé que j'avais deux fenêtres git-bash ouvertes. , et n'avait pas utilisé CTLR+C pour arrêter le déploiement précédent .

j'ai été rencontré avec:

d'État HTTP 404 – not Found Type de Rapport d'État

Message /si-étudiant-test.jsp

Description le serveur origin n'a pas trouvé de représentation actuelle pour la ressource cible ou n'est pas disposé à divulguer qu'un exister.

Apache Tomcat / 8.5.31

ci-dessous est plus de détails pour le scénario #3:


scénario 3.1: Le chemin du paquet de la classe servlet est erroné dans votre site web.fichier xml.

il doit correspondre au paquet déclaration en haut de la page de votre classe java servlet.

fichier: my_stuff / MyClass.java :

   package my_stuff;

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

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

scénario 3.2:

Vous mettez le mal " package " déclaration au sommet de votre myClass.fichier java.

par exemple:

Fichier: " /my_stuff " dossier

vous écrivez par erreur:

package com.my_stuff

c'est délicat parce que:

1: la compilation maven (paquet mvn) ne signalera aucune erreur ici.

2: ligne de classe servlet dans le web.xml peut avoir le chemin correct du paquet. Par exemple:

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

Pile Utilisée: Notepad++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :

0
répondu J.M.I. MADISON 2018-07-27 00:26:22