Serwlet zwraca „Status HTTP 404 Żądany zasób (/ serwlet) jest niedostępny”

99

Mam formularz HTML w pliku JSP w moim WebContent/jspsfolderze. Mam klasę serwletu servlet.javaw moim domyślnym pakiecie w srcfolderze. W moim web.xmljest odwzorowany jako /servlet.

Wypróbowałem kilka adresów URL w actionatrybucie formularza HTML:

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

Ale żadna z nich nie działa. Wszystkie zwracają błąd HTTP 404, jak poniżej w Tomcat 6/7/8:

Status HTTP 404 - / servlet

Opis : Żądany zasób (/ serwlet) jest niedostępny.

Lub jak poniżej w Tomcat 8.5 / 9:

Stan HTTP 404 - nie znaleziono

Wiadomość : / servlet

Opis : serwer pochodzenia nie znalazł bieżącej reprezentacji zasobu docelowego lub nie chce ujawnić, że istnieje

Dlaczego to nie działa?

pongahead
źródło

Odpowiedzi:

131

Umieść klasę serwletu w pliku package

Przede wszystkim umieść klasę serwletu w Javie package. Powinieneś zawsze umieszczać w pakiecie klasy Java, które można ponownie wykorzystać, w przeciwnym razie będą one niewidoczne dla klas znajdujących się w pakiecie, takich jak sam serwer. W ten sposób eliminujesz potencjalne problemy specyficzne dla środowiska. Serwlety bez pakietów działają tylko w określonych kombinacjach Tomcat + JDK i nigdy nie należy na tym polegać.

W przypadku „zwykłego” projektu IDE, klasę należy umieścić w strukturze pakietu w folderze „Java Resources”, a nie „WebContent”, dotyczy to plików internetowych, takich jak JSP. Poniżej znajduje się przykład struktury folderów w domyślnym projekcie Eclipse Dynamic Web Project w widoku Nawigatora :

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

W przypadku projektu Maven klasa musi być umieszczona w strukturze pakietu wewnątrz, main/java a więc nie dotyczy to npmain/resources . Plików nieklasowych . Poniżej znajduje się przykład struktury folderów w domyślnym projekcie aplikacji internetowej Maven, jak widać w widoku Nawigatora Eclipse :

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

Zwróć uwagę, że /jspspodfolder nie jest bezwzględnie potrzebny. Możesz nawet obejść się bez tego i umieścić plik JSP bezpośrednio w katalogu głównym zawartości sieciowej / aplikacji internetowej, ale przejmuję to z twojego pytania.

Ustaw adres URL serwletu w url-pattern

Adres URL serwletu jest określony jako „wzorzec adresu URL” odwzorowania serwletu. Absolutnie nie jest to nazwa klasy / nazwa pliku klasy serwletu. Wzorzec adresu URL należy określić jako wartość @WebServletadnotacji.

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

Jeśli chcesz obsługiwać parametry ścieżki, takie jak /servlet/foo/bar, /servlet/*zamiast tego użyj wzorca adresu URL . Zobacz także parametry serwletu i ścieżki, takie jak / xyz / {wartość} / test, jak mapować w web.xml?

@WebServlet działa tylko na Servlet 3.0 lub nowszym

Aby użyć @WebServlet, musisz tylko upewnić się, że twój web.xmlplik, jeśli taki istnieje (jest opcjonalny od Servlet 3.0), jest zadeklarowany zgodnie z wersją Servlet 3.0+, a zatem nie jest zgodny, np. W wersji 2.5 lub niższej . Poniżej znajduje się kompatybilny z Servlet 4.0 (który pasuje do Tomcat 9+, WildFly 11+, Payara 5+ itp.).

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

Lub, jeśli nie korzystasz jeszcze z Servlet 3.0+ (np. Tomcat 6 lub starszy), usuń @WebServletadnotację.

package com.example;

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

Zamiast web.xmltego zarejestruj serwlet w następujący sposób:

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

Zwróć uwagę, że nie powinieneś używać obu sposobów. Użyj konfiguracji opartej na adnotacjach lub konfiguracji opartej na języku XML. Gdy masz oba, konfiguracja oparta na języku XML zastąpi konfigurację opartą na adnotacjach.

Weryfikacja kompilacji / wdrożenia

Jeśli używasz narzędzia do budowania, takiego jak Eclipse i / lub Maven, musisz mieć absolutną pewność, że skompilowany plik klasy serwletu znajduje się w swojej strukturze pakietu w /WEB-INF/classesfolderze utworzonego pliku WAR. W przypadku package com.example; public class YourServlet, musi znajdować się w /WEB-INF/classes/com/example/YourServlet.class. W przeciwnym razie napotkasz @WebServletrównież błąd 404 lub <servlet>błąd HTTP 500, jak poniżej:

Stan HTTP 500

Błąd podczas tworzenia instancji klasy serwletu com.example.YourServlet

I znajdź w dzienniku serwera a java.lang.ClassNotFoundException: com.example.YourServlet, po którym z java.lang.NoClassDefFoundError: com.example.YourServletkolei następuje a, po którym następuje javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet.

Łatwym sposobem sprawdzenia, czy serwlet jest poprawnie skompilowany i umieszczony w ścieżce klas, jest pozwolenie narzędziu budującemu na utworzenie pliku WAR (np. Projekt kliknięcia prawym przyciskiem, eksport> plik WAR w Eclipse), a następnie sprawdzenie jego zawartości za pomocą narzędzia ZIP. Jeśli brakuje klasy serwletu /WEB-INF/classeslub jeśli eksport powoduje błąd, to projekt jest źle skonfigurowany lub niektóre domyślne ustawienia IDE / projektu zostały omyłkowo przywrócone (np. Projekt> Buduj automatycznie został wyłączony w Eclipse).

Musisz również upewnić się, że ikona projektu nie ma czerwonego krzyżyka wskazującego błąd kompilacji. Dokładny błąd można znaleźć w widoku Problemy ( Okno> Pokaż widok> Inne ... ). Zwykle komunikat o błędzie można umieścić w Google. Jeśli nie masz pojęcia, najlepiej jest uruchomić ponownie od zera i nie zmieniać żadnych domyślnych ustawień IDE / projektu. W przypadku korzystania z Eclipse instrukcje można znaleźć w artykule Jak zaimportować interfejs API javax.servlet do mojego projektu Eclipse?

Testowanie serwletu indywidualnie

Pod warunkiem, że serwer działa localhost:8080i że WAR jest pomyślnie wdrożony na ścieżce kontekstu /contextname(która domyślnie jest nazwą projektu IDE, z uwzględnieniem wielkości liter!), A inicjalizacja serwletu nie zakończyła się niepowodzeniem (odczyt dzienników serwera dla każdego wdrożenia / komunikaty o powodzeniu / niepowodzeniu serwletu oraz rzeczywista ścieżka kontekstowa i mapowanie serwletu), to serwlet z wzorcem adresu URL /servletjest dostępny pod adresem http://localhost:8080/contextname/servlet.

Możesz po prostu wpisać go bezpośrednio w pasku adresu przeglądarki, aby przetestować go niezauważalnie. Jeśli doGet()jest poprawnie zastąpiony i zaimplementowany, zobaczysz jego wynik w przeglądarce. Lub jeśli nie masz żadnego doGet()lub jeśli wywołuje to nieprawidłowo super.doGet(), to zostanie wyświetlony błąd „ HTTP 405: metoda HTTP GET nie jest obsługiwana przez ten adres URL ” (który jest nadal lepszy niż 404, ponieważ 405 jest dowodem, że aplet faktycznie znajduje się).

Zastępowanie service()jest złą praktyką, chyba że odkrywasz na nowo framework MVC - co jest bardzo mało prawdopodobne, jeśli dopiero zaczynasz od serwletów i nie masz pojęcia o problemie opisanym w bieżącym pytaniu;) Zobacz także aplikacje internetowe wzorce projektowe .

Niezależnie od tego, jeśli aplet już zwraca 404, gdy jest testowany przypadkowo, to całkowicie bezcelowe jest próbowanie zamiast tego z formularzem HTML. Logicznie rzecz biorąc, jest zatem całkowicie bezcelowe dołączanie jakichkolwiek formularzy HTML w pytaniach dotyczących błędów 404 z serwletu.

Odwoływanie się do adresu URL serwletu z HTML

Po upewnieniu się, że serwlet działa dobrze, gdy jest wywoływany indywidualnie, możesz przejść do HTML. Jeśli chodzi o konkretny problem z formularzem HTML, <form action>wartością musi być prawidłowy adres URL. To samo dotyczy <a href>. Musisz zrozumieć, jak działają bezwzględne / względne adresy URL. Wiesz, URL to adres internetowy, który możesz wpisać / zobaczyć na pasku adresu przeglądarki internetowej. Jeśli określasz względny adres URL jako akcję formularza, tj. Bez http://schematu, staje się on względny w stosunku do bieżącego adresu URL, jak widać na pasku adresu przeglądarki internetowej. W związku z tym absolutnie nie jest to związane z lokalizacją pliku JSP / HTML w strukturze folderów WAR serwera, jak wydaje się sądzić wielu początkujących.

Tak więc, zakładając, że strona JSP z formularza HTML otwiera http://localhost:8080/contextname/jsps/page.jspi trzeba złożyć do serwletu znajduje się http://localhost:8080/contextname/servlettu kilka przypadków (zauważ, że można bezpiecznie zastąpić <form action>z <a href>tutaj):

  • Akcja formularza jest przesyłana do adresu URL z początkowym ukośnikiem.

      <form action="/servlet">
    

    Początkowy ukośnik /wyznacza adres URL względem domeny, więc formularz zostanie przesłany do

      http://localhost:8080/servlet
    

    Ale prawdopodobnie spowoduje to 404, ponieważ jest w złym kontekście.


  • Akcja formularza jest przesyłana do adresu URL bez początkowego ukośnika.

      <form action="servlet">
    

    To sprawia, że ​​adres URL jest powiązany z bieżącym folderem bieżącego adresu URL, a zatem formularz zostanie przesłany do

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

    Ale prawdopodobnie spowoduje to 404, ponieważ znajduje się w niewłaściwym folderze.


  • Akcja formularza jest przesyłana do adresu URL, który przechodzi o jeden folder w górę.

      <form action="../servlet">
    

    Spowoduje to przejście o jeden folder w górę (dokładnie tak, jak w przypadku ścieżek systemu plików na dysku lokalnym!), A zatem formularz zostanie przesłany do

      http://localhost:8080/contextname/servlet
    

    Ten musi działać!


  • Jednak podejście kanoniczne polega na tym, że adres URL jest zależny od domeny, aby nie trzeba było ponownie naprawiać adresów URL, gdy zdarzy się przenieść pliki JSP do innego folderu.

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

    To wygeneruje

      <form action="/contextname/servlet">
    

    Który w ten sposób zawsze zostanie przesłany pod właściwy adres URL.


Używaj prostych cudzysłowów w HTML

Musisz mieć absolutną pewność, że używasz prostych cudzysłowów w atrybutach HTML, takich jak action="..."lub, action='...'a zatem nie używasz cudzysłowów takich jak action=”...”lub action=’...’. Cudzysłowy nie są obsługiwane w HTML i staną się po prostu częścią wartości. Uważaj podczas kopiowania i wklejania fragmentów kodu z blogów! Wiadomo, że niektóre silniki blogów, zwłaszcza Wordpress, domyślnie używają tak zwanych „inteligentnych cudzysłowów”, które w ten sposób również zniekształcają cytaty we fragmentach kodu. Z drugiej strony, zamiast kopiować i wklejać kod, spróbuj po prostu wpisać kod samodzielnie. Dodatkową zaletą faktycznego przechodzenia kodu przez mózg i palce jest to, że w dłuższej perspektywie znacznie lepiej zapamiętasz i zrozumiesz kod, a także staniesz się lepszym programistą.

Zobacz też:

Inne przypadki błędu HTTP stanu 404:

BalusC
źródło
1
web-app version = "3.1" używając glassfish, mogłem przetestować mój serwlet pojedynczo dobrze, gdy miałem mapowanie w web.xml ORAZ adnotację. Usunąłem mapowanie i zostawiłem adnotację, ponieważ mam najnowszą wersję, ale wtedy pojawia się błąd 404?
SallyRothroat
1
Może się to zdarzyć, jeśli włączysz biblioteki serwletów 2.5 lub starsze do samej aplikacji internetowej, zamiast polegać na docelowym środowisku wykonawczym, które samo zapewni biblioteki serwletów.
BalusC
@xdola: Jest rzeczywiście kruchy, ponieważ zależy od identyfikatora URI żądania. Po prostu przeczytaj odpowiedź, aby wyjaśnić swój problem i jakie jest właściwe podejście.
BalusC
4

Scenariusz nr 1: Jesteś przypadkowym ruchom ponownie rozmieszczone w wierszu poleceń podczas kocur został już uruchomiony .

Krótka odpowiedź: zatrzymaj Tomcat, usuń folder docelowy , pakiet mvn, a następnie przeprowadź ponowne wdrożenie


Scenariusz nr 2: request.getRequestDispatcher („ MIS_SPELLED_FILE_NAME .jsp”)

Krótka odpowiedź: Sprawdź pisownię nazwy pliku , upewnij się, że wielkość liter jest poprawna.


Scenariusz # 3: Wyjątki nie znaleziono klasy (odpowiedź umieszczona tutaj, ponieważ: Pytanie # 17982240) ( wyjątek java.lang.ClassNotFoundException dla serwletu w tomcat z zaćmieniem ) (został oznaczony jako duplikat i skierował mnie tutaj)

Krótka odpowiedź nr 3.1: plik web.xml ma nieprawidłową ścieżkę do pakietu w tagu klasy serwletu.

Krótka odpowiedź nr 3.2: plik java zawiera nieprawidłową instrukcję importu.


Poniżej znajdują się dalsze szczegóły dotyczące scenariusza nr 1:


1: Zatrzymaj Tomcat

  • Opcja 1: przez CTRL + C w terminalu.
  • Opcja 2: (terminal zamknięty, gdy Tomcat nadal działa)
  • ------------ 2.1: naciśnij: Windows + R -> wpisz: " services.msc "
  • ------------ 2.2: Znajdź „Apache Tomcat #. # Tomcat #” w kolumnie Nazwa listy.
  • ------------ 2.3: Kliknięcie prawym przyciskiem myszy -> „ stop

2: Usuń folder „docelowy”. (mvn clean ci tutaj nie pomoże)

3: pakiet mvn

4: YOUR_DEPLOYMENT_COMMAND_HERE

(Mój: java -jar target / dependency / webapp-runner.jar --port 5190 target / *. War)

Pełna historia:


Przypadkowo otworzyłem nowe okno git-bash i próbowałem wdrożyć plik .war dla mojego projektu heroku przez:

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

Po niepowodzeniu wdrażania zdałem sobie sprawę, że mam otwarte dwa okna git-bash i nie użyłem CTLR + C do zatrzymania poprzedniego wdrożenia .

Spotkałem się z:

Stan HTTP 404 - Nie znaleziono Typ raportu o stanie

Wiadomość /if-student-test.jsp

Opis Serwer pochodzenia nie znalazł bieżącej reprezentacji zasobu docelowego lub nie chce ujawnić, że taki istnieje.

Apache Tomcat / 8.5.31

Poniżej znajdują się dalsze szczegóły dotyczące scenariusza nr 3:


SCENARIUSZ 3.1: Ścieżka do pakietu klasy serwletu w pliku web.xml jest nieprawidłowa.

Powinien być zgodny z instrukcją pakietu na początku klasy serwletu Java.

Plik: my_stuff / MyClass.java :

   package my_stuff;

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

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

SCENARIUSZ 3.2:

Na początku pliku myClass.java umieściłeś niewłaściwą instrukcję „ pakiet ”.

Na przykład:

Plik znajduje się w folderze : „ / my_stuff

Błędnie piszesz:

package com.my_stuff

Jest to trudne, ponieważ:

1: Kompilacja maven (pakiet mvn) nie zgłosi tutaj żadnych błędów.

2: wiersz klasy serwletu w pliku web.xml może mieć PRAWIDŁOWĄ ścieżkę pakietu. Na przykład:

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

Używany stos: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :

JMI MADISON
źródło
Twoja nazwa_aplikacji.war, a tym samym nazwa folderu rozbitego, nie jest zgodna z oczekiwaną nazwą, na przykład gdy plik wojenny ma wersję taką jak AppName-1.0-SNAPSHOT.war i próbujesz / AppName /.
jla
0

Rozwiązanie dla HTTP Status 404NetBeans IDE: Kliknij prawym przyciskiem myszy projekt i przejdź do właściwości projektu, a następnie kliknij Uruchom, a następnie wprowadź względny adres URL projektu, np index.jsp.

  1. Projekt-> Właściwości
  2. Kliknij Uruchom
  3. Względny adres URL: /index.jsp (wybierz główny adres URL projektu)

wprowadź opis obrazu tutaj

LUB Imon
źródło
0

Mój problem polegał na tym, że w mojej metodzie brakowało adnotacji @RequestBody. Po dodaniu adnotacji nie otrzymałem już wyjątku 404.

THE_DOM
źródło
0

Wykonaj następujące dwa kroki. Mam nadzieję, że rozwiąże to problem „404 not found” na serwerze tomcat podczas tworzenia aplikacji serwletu java.

Krok 1: Right click on the server(in the server explorer tab)->Properties->Switch Location from workspace metadata to tomcat server

Krok 2: Double Click on the server(in the server explorer tab)->Select Use tomcat installation option inside server location menu

Sajal Saha
źródło
0

Usunąłem starą bibliotekę internetową, taką jak biblioteki Spring Framework. I zbuduj nową ścieżkę dla bibliotek. Wtedy to działa.

pajarnas
źródło
0

Stary wątek, ale ponieważ nie znalazłem go nigdzie indziej, oto jeszcze jedna możliwość:

Jeśli używasz servlet-api 3.0+ , twój web.xml NIE może zawierać metadata-complete="true"atrybutu

wprowadź opis obrazu tutaj

To mówi tomcatowi, aby odwzorował serwlety przy użyciu danych podanych w web.xmlzamiast używania @WebServletadnotacji.

Chaitanya
źródło
0

Przede wszystkim uruchom IDE jako administrator. Następnie kliknij prawym przyciskiem myszy folder projektu -> Aspekty projektu i upewnij się, że wersja Java jest ustawiona poprawnie. Na moim komputerze. (Na przykład 1.8) Teraz powinno działać.

Nie uruchamiaj po prostu swojego serwera, na przykład Wildfly, używając cmd. Musi zostać uruchomiony w IDE i teraz przejdź do adresu URL twojego lokalnego hosta. Przykład: http: // localhost: 8080 / HelloWorldServlet / HelloWorld

Selby Khuzwayo
źródło
0

Poprawka, która działała dla mnie, to (jeśli używasz Mavena): Kliknij prawym przyciskiem myszy swój projekt, Maven -> Zaktualizuj projekt. Może to spowodować inny błąd związany z JDK i innymi bibliotekami (w moim przypadku łącznikiem MySQL), ale po ich naprawieniu pierwotny problem powinien zostać naprawiony!

joseph zhao
źródło
0

Jeśli chcesz otworzyć serwlet z javascriptem bez użycia przycisku „formularz” i „wyślij”, oto poniższy kod:

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

Klucz:

1) button-id: Znacznik „id”, który nadajesz przyciskowi w pliku html / jsp.

2) pełna-ścieżka-serwletu: ścieżka wyświetlana w przeglądarce po uruchomieniu samego serwletu

matak8s
źródło
0

Mapowanie w web.xml jest tym, co zrobiłem: -

  1. Jeśli istnieje inny pakiet stworzony dla nowego programu, musimy wspomnieć: -

nazwa_pakietu.nazwa pliku między otwarciem a zamknięciem znacznika klasy serwletu w pliku xml.

  1. Jeśli mapujesz swoje pliki w formacie XML i nie działają one lub nie wyświetlają błędów, skomentuj wiersz adnotacji w kodzie w odpowiednich plikach.

Obie metody nie działają ze sobą, więc albo używam metody adnotacji do plików wymienionych podczas tworzenia serwletu lub sposobu mapowania, a następnie usuwam lub komentuję linię adnotacji. Na przykład:

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

Komentowanie wiersza adnotacji w kodzie w odpowiednim pliku, jeśli mapowanie w formacie XML zostało wykonane.

//@WebServlet("/FirstServ")
//@WebServlet("/SecondServ")
Sidharth Jain
źródło
0

Jeśli jest tutaj ktoś, kto używa MySQL i czuł, że kod działał poprzedniego dnia, a teraz nie, to chyba musisz otworzyć MySQL CLI lub MySQL Workbench i po prostu raz połączyć się z bazą danych. Po nawiązaniu połączenia baza danych zostaje również połączona z aplikacją Java. Kiedyś otrzymywałem błąd Hibernate Dialect informujący, że coś jest nie tak z com.mysql.jdbc.Driver. Myślę, że MySQL na niektórych komputerach ma problem z uruchamianiem. To rozwiązało dla mnie.

Tejas Naresh Suvarna
źródło
0

Jeśli jesteś studentem i nie znasz języka Java, może występować problem z plikiem web.xml.

  1. Spróbuj usunąć plik web.xml.
  2. Po drugie, sprawdź, czy zmienne ścieżki są poprawnie ustawione, czy nie.
  3. Zrestartuj serwer Tomcat lub komputer.

Twój problem na pewno zostanie rozwiązany.

Mudassar Malik
źródło
-1

Sprawdź, czy kontekstowy katalog główny nie może być pusty .

Jeśli używasz eclipse:
kliknij prawym przyciskiem myszy , wybierz właściwości , a następnie ustawienia projektu internetowego . Sprawdź, czy kontekstowy katalog główny nie może być pusty

Wiem Rachman
źródło