Сервлет повертає “HTTP Status 404 Запитаний ресурс (/ сервлет) недоступний”


98

У моїй WebContent/jspsпапці є форма HTML у файлі JSP . У мене є сервлетний клас servlet.javaу моєму пакунку за замовчуванням у srcпапці. У моєму web.xmlвоно відображається як /servlet.

Я спробував кілька URL-адрес в actionатрибуті форми HTML:

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

Але жодне з них не працює. Всі вони продовжують повертати помилку HTTP 404, як показано нижче в Tomcat 6/7/8:

Статус HTTP 404 - / сервлет

Опис : Запитаний ресурс (/ сервлет) недоступний.

Або як показано нижче в Tomcat 8.5 / 9:

Статус HTTP 404 - не знайдено

Повідомлення : / сервлет

Опис : Початковий сервер не знайшов поточного подання для цільового ресурсу або не бажає розкривати, що такий існує

Чому це не працює?

Відповіді:


130

Помістіть клас сервлету в a package

Перш за все, помістіть клас сервлетів в Java package. Завжди слід поміщати загальнодоступні багаторазові класи Java у пакет, інакше вони невидимі для класів, що знаходяться в пакеті, наприклад, самого сервера. Таким чином ви усуваєте потенційні проблеми, пов'язані з навколишнім середовищем. Безпакетні сервлети працюють лише у певних комбінаціях Tomcat + JDK, і на це ніколи не можна покладатися.

У випадку "простого" проекту IDE клас потрібно розмістити у структурі пакету всередині папки "Ресурси Java", а не "WebContent", це стосується веб-файлів, таких як JSP. Нижче наведено приклад структури папок за замовчуванням Динамічного веб-проекту Eclipse, як показано в поданні Навігатора :

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

У разі проекту Maven клас потрібно розмістити всередині його структури пакета, main/java і, отже, не, наприклад main/resources, це стосується некласових файлів . Нижче наведено приклад структури папок за замовчуванням проекту веб-програми Maven, як показано в поданні Навігатора Eclipse :

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

Зверніть увагу, що /jspsпідпапка не є суворо необхідною. Ви навіть можете обійтися без нього і розмістити файл JSP безпосередньо в кореневій папці webcontent / webapp, але я просто беру на себе це з вашого запитання.

Встановити URL-адресу сервлета в url-pattern

URL-адреса сервлета вказана як "шаблон URL-адреси" відображення сервлета. Це абсолютно не за визначенням ім’я класу / ім’я файлу класу сервлета. Шаблон URL-адреси слід вказати як значення @WebServletанотації.

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

Якщо ви хочете підтримувати такі параметри шляху /servlet/foo/bar, /servlet/*замість цього використовуйте шаблон URL . Дивіться також параметри сервлету та шляху, такі як / xyz / {value} / test, як зіставити в web.xml?

@WebServlet працює лише на Servlet 3.0 або новіших версіях

Для використання @WebServletвам потрібно лише переконатись, що ваш web.xmlфайл, якщо такий є (необов’язковий, оскільки Servlet 3.0), оголошений відповідною версією Servlet 3.0+ і, таким чином, не відповідає, наприклад, версії 2.5 або нижче . Нижче наведено сумісний сервлет 4.0 (який відповідає Tomcat 9+, WildFly 11+, Payara 5+ тощо).

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

Або, якщо ви ще не користуєтесь Servlet 3.0+ (наприклад, Tomcat 6 або старіша версія), видаліть @WebServletанотацію.

package com.example;

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

І зареєструйте сервлет замість цього web.xmlтаким чином:

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

Отже, зауважте, що вам не слід користуватися обома способами. Використовуйте конфігурацію на основі анотацій або конфігурацію на основі XML. Коли у вас є обидва, тоді конфігурація на основі XML замінить конфігурацію на основі анотацій.

Перевірка побудови / розгортання

Якщо ви використовуєте інструмент побудови, такий як Eclipse та / або Maven, то вам потрібно бути абсолютно впевненим, що скомпільований файл класу сервлетів знаходиться у своїй структурі пакету в /WEB-INF/classesпапці створеного файлу WAR. У разі package com.example; public class YourServlet, він повинен знаходитися в /WEB-INF/classes/com/example/YourServlet.class. В іншому випадку ви зіткнетеся з @WebServletпомилкою 404 або <servlet>помилкою HTTP 500, як показано нижче:

Статус HTTP 500

Помилка створення копії класу сервлетів com.example.YourServlet

І знайдіть у журналі сервера a java.lang.ClassNotFoundException: com.example.YourServlet, за яким слідує a java.lang.NoClassDefFoundError: com.example.YourServlet, у свою чергу слідує javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet.

Найпростіший спосіб перевірити, чи правильно скомпільований та розміщений сервлет у шляху до класу, - це дозволити інструменту побудови створити файл WAR (наприклад, проект клацання правою кнопкою миші, Експорт> Файл WAR у Eclipse), а потім перевірити його вміст за допомогою інструмента ZIP. Якщо клас сервлета відсутній /WEB-INF/classes, або якщо експорт спричиняє помилку, проект погано налаштований або деякі типові налаштування IDE / конфігурації проекту були помилково скасовані (наприклад, Проект> Автоматична побудова вимкнена в Eclipse).

Також потрібно переконатися, що на піктограмі проекту немає червоного хрестика, що вказує на помилку збірки. Ви можете знайти точну помилку у вікні Проблеми ( Вікно> Показати вигляд> Інше ... ). Зазвичай повідомлення про помилку є нормальним для Googlable. Якщо у вас немає поняття, найкраще перезапустити з нуля та не торкатися стандартних налаштувань IDE / проекту. Якщо ви використовуєте Eclipse, ви можете знайти інструкції в розділі Як імпортувати API javax.servlet у своєму проекті Eclipse?

Тестування сервлету індивідуально

За умови, що сервер працює localhost:8080і що WAR успішно розгорнуто на контекстному шляху /contextname(який за замовчуванням відповідає імені проекту IDE, чутливим до регістру!), А сервлет не провалив свою ініціалізацію (читайте журнали сервера для будь-якого розгортання / повідомлення про успіх / помилку сервлету та фактичний шлях контексту та зіставлення сервлетів), тоді сервлет із шаблоном URL-адреси /servletдоступний за адресою http://localhost:8080/contextname/servlet.

Ви можете просто ввести його прямо в адресному рядку браузера, щоб перевірити його невимушено. Якщо його doGet()правильно перевизначити і реалізувати, ви побачите його вихід у браузері. Або якщо у вас їх немає, doGet()або якщо він викликає неправильно super.doGet(), буде показано помилку " HTTP 405: метод HTTP GET не підтримується цією URL-адресою " (що все-таки краще, ніж 404, оскільки 405 є свідченням того, що сервлет насправді знайдено).

Перевизначення service()є поганою практикою, якщо ви не винаходите фреймворк MVC - що дуже малоймовірно, якщо ви тільки починаєте з сервлетів і не знаєте про проблему, описану в поточному питанні;) Див. Також веб-додатки Design Patterns .

Незалежно від того, якщо сервлет вже повертає 404 при невипробуваному тестуванні, то цілком безглуздо намагатися замість нього використовувати HTML-форму. Логічно, отже, також абсолютно безглуздо включати будь-яку форму HTML у питання про помилки 404 із сервлету.

Посилання на URL-адресу сервлета з HTML

Переконавшись, що сервлет працює нормально при індивідуальному виклику, ви можете перейти до HTML. Що стосується вашої конкретної проблеми з формою HTML, <form action>значення має бути дійсною URL-адресою. Те саме стосується <a href>. Ви повинні розуміти, як працюють абсолютні / відносні URL-адреси. Знаєте, URL-адреса - це веб-адреса, яку ви можете ввести / побачити в адресному рядку веб-браузера. Якщо ви вказуєте відносну URL-адресу як дію форми, тобто без http://схеми, тоді вона стає відносно поточної URL-адреси, як ви бачите в адресному рядку веб-браузера. Таким чином, це абсолютно не відносно розташування файлу JSP / HTML у структурі папок WAR сервера, як думають багато початківців.

Таким чином, за умови , що сторінка JSP з HTML - формою відкриваються http://localhost:8080/contextname/jsps/page.jsp, і ви повинні представити сервлет , розташований в http://localhost:8080/contextname/servlet, ось кілька випадків (зверніть увагу , що ви можете спокійно замінити <form action>з <a href>тут):

  • Дія форми подається на URL-адресу з косою рискою.

      <form action="/servlet">
    

    Провідна коса риса /робить URL-адресу відносно домену, таким чином форма буде подана

      http://localhost:8080/servlet
    

    Але це, швидше за все, призведе до 404, оскільки це в неправильному контексті.


  • Дія форми подається на URL-адресу без косої риски.

      <form action="servlet">
    

    Це робить URL-адресу відносно поточної папки поточної URL-адреси, таким чином форма буде надіслана

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

    Але це, швидше за все, призведе до 404, оскільки він знаходиться в неправильній папці.


  • Дія форми подається на URL-адресу, яка йде на одну папку вгору.

      <form action="../servlet">
    

    Це підніметься на одну папку вгору (точно так само, як у шляхах до файлової системи на локальному диску!), Таким чином форма буде подана

      http://localhost:8080/contextname/servlet
    

    Цей повинен працювати!


  • Однак канонічний підхід полягає в тому, щоб зробити URL-адресу відносною для домену, щоб вам не потрібно було ще раз фіксувати URL-адреси, коли трапляється, що ви переміщуєте файли JSP в іншу папку.

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

    Це генерує

      <form action="/contextname/servlet">
    

    Який, таким чином, завжди буде подавати потрібну URL-адресу.


Використовуйте прямі лапки в HTML

Вам потрібно бути абсолютно впевненим, що ви використовуєте прямі лапки в атрибутах HTML на зразок action="..."або, action='...'а отже, не фігурні лапки на кшталт action=”...”або action=’...’. Фігурні лапки не підтримуються в HTML, і вони просто стануть частиною значення. Слідкуйте за тим, щоб копіювати фрагменти коду з блогів! Деякі двигуни блогів, зокрема Wordpress, за замовчуванням використовують так звані "розумні лапки", які таким чином також пошкоджують лапки у фрагментах коду таким чином. З іншого боку, замість копіювання коду, спробуйте просто набрати код самостійно. Додатковою перевагою фактичного проходження коду через ваш мозок та пальці є те, що це змусить вас пам’ятати і розуміти код набагато краще в довгостроковій перспективі, а також зробить вас кращим розробником.

Дивіться також:

Інші випадки помилки HTTP Status 404:


1
web-app version = "3.1", використовуючи glassfish, я міг би протестувати свій сервлет по-окремому, коли в мене було відображення в web.xml І анотація. Я видалив відображення і залишив анотацію, оскільки маю останню версію, але тоді я отримаю помилку 404?
SallyRothroat

1
Це може статися, якщо ви включите серверлет 2.5 або старіші бібліотеки в сам веб-додаток, а не покладаєтесь на цільовий час виконання, щоб забезпечити бібліотеки сервлетів самостійно.
BalusC

@xdola: Це справді крихко, оскільки це залежить від URI запиту. Просто прочитайте відповідь на пояснення щодо вашої проблеми та який правильний підхід.
BalusC,

4

Сценарій №1: Ви випадково повторно розгорнули командний рядок, коли tomcat вже працював .

Коротка відповідь: Зупиніть Tomcat, видаліть цільову папку , пакет mvn, а потім повторно розгорніть


Сценарій №2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME .jsp")

Коротка відповідь: Перевірте написання імені файлу , переконайтеся, що регістр правильний.


Сценарій №3: Винятки класу не знайдено (відповідь поставлено тут, оскільки: Питання # 17982240) ( java.lang.ClassNotFoundException для сервлета в tomcat з затемненням ) (позначено як дублікат і спрямовано сюди)

Коротка відповідь № 3.1: web.xml має неправильний шлях до пакета в тезі класу сервлетів.

Короткий відповідь №3.2: у файлі Java неправильний оператор імпорту.


Нижче наведено додаткові відомості про сценарій №1:


1: Зупиніть Tomcat

  • Варіант 1: Через CTRL + C в терміналі.
  • Варіант 2: (термінал закрито, поки tomcat все ще працює)
  • ------------ 2.1: натисніть: Windows + R -> тип: " services.msc "
  • ------------ 2.2: Знайдіть "Apache Tomcat #. # Tomcat #" у стовпці Ім'я списку.
  • ------------ 2.3: Клацніть правою кнопкою миші -> " зупинити "

2: Видаліть папку "target". (mvn clean вам тут не допоможе)

3: пакет mvn

4: ВАШЕ_ДЕПЛОЙМЕНТУ_КОМАНДУ_ТУТ

(Шахта: java -jar target / dependency / webapp-runner.jar --port 5190 target / *. War)

Повна історія спини:


Випадково відкрив нове вікно git-bash і спробував розгорнути файл .war для мого проекту heroku за допомогою:

java -jar ціль / залежність / webapp-runner.jar --port 5190 ціль / *. війна

Після невдалого розгортання я зрозумів, що у мене відкрито два вікна git-bash і не використовував CTLR + C для зупинки попереднього розгортання .

Мене зустріли:

Статус HTTP 404 - Не знайдено Тип звіту про стан

Повідомлення /if-student-test.jsp

Опис Початковий сервер не знайшов поточного подання для цільового ресурсу або не бажає розкривати, що такий існує.

Apache Tomcat / 8.5.31

Нижче наведено додаткові відомості про сценарій №3:


СЦЕНАРІЙ 3.1: Шлях до пакета класу сервлетів неправильний у вашому файлі web.xml.

Він повинен ВІДПОВІДАТИ інструкцію з пакетом у верхній частині вашого класу сервлетів Java.

Файл: my_stuff / MyClass.java :

   package my_stuff;

Файл: PRJ_ROOT / src / main / webapp / WEB-INF / web.xml

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

СЦЕНАРІЙ 3.2:

Ви поставили неправильний " пакет" вираз " у верхній частині файлу myClass.java.

Наприклад:

Файл знаходиться в: " / my_stuff папці "

Ви помилково пишете:

package com.my_stuff

Це складно, оскільки:

1: Збірка maven (пакет mvn) тут не повідомляє про помилки.

2: рядок класу сервлетів у web.xml може мати ПРАВИЛЬНИЙ шлях до пакету. Наприклад:

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

Використовуваний стек: Notepad ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10 :


Ваше ім'я AppName.war і, отже, назва папки, що розігралася, не відповідає вашому очікуваному імені, наприклад, коли ваш військовий файл має версію, як AppName-1.0-SNAPSHOT.war, і ви намагаєтесь / AppName /.
jla

0

Рішення для HTTP Status 404 IDE NetBeans: Клацніть правою кнопкою миші на своєму проекті та перейдіть до властивостей вашого проекту, потім натисніть на запустити, а потім введіть відносну URL-адресу проекту, як index.jsp.

  1. Проект-> Властивості
  2. Клацніть на Виконати
  3. Відносна URL-адреса: /index.jsp (Виберіть кореневу URL-адресу проекту)

введіть тут опис зображення


0

Моя проблема полягала в тому, що в моєму методі відсутня анотація @RequestBody. Після додавання анотації я більше не отримував виняток 404.


0

Виконайте наступні два кроки. Я сподіваюся, це вирішить проблему "404 не знайдено" на сервері tomcat під час розробки програми сервлету Java.

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

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


0

Я видалив стару веб-бібліотеку, таку як весняні фреймворкові бібліотеки. І побудувати новий шлях бібліотек. Тоді це працює.


0

Стара тема, але оскільки я не знайшов її в іншому місці, є ще одна можливість:

Якщо ви використовуєте сервлет-api 3.0+ , тоді ваш web.xml НЕ повинен містити metadata-complete="true"атрибут

введіть тут опис зображення

Це вказує tomcat зіставляти сервлети, використовуючи дані, подані web.xmlзамість @WebServletанотації.


0

Перш за все, запустіть свою IDE як адміністратор. Після цього клацніть правою кнопкою миші папку проекту -> Грані проекту та переконайтеся, що Версія Java встановлена ​​правильно. На моєму ПК. (Для прикладу 1.8) Тепер це має спрацювати.

Не просто запускайте свій сервер, наприклад Wildfly, використовуючи cmd. Його потрібно запустити в IDE, а тепер відвідайте URL-адресу вашого localhost. Приклад: http: // localhost: 8080 / HelloWorldServlet / HelloWorld


0

Виправлення, яке спрацювало для мене: (якщо ви використовуєте Maven): клацніть правою кнопкою миші ваш проект, Maven -> оновити проект. Це може призвести до іншої помилки з JDK та іншими бібліотеками (у моєму випадку з'єднувачем MySQL), але як тільки ви їх виправите, ваша вихідна проблема повинна бути виправлена!


0

Якщо ви хочете відкрити сервлет за допомогою JavaScript, не використовуючи кнопку «форма» та «подати», ось такий код:

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

Ключ:

1) button-id: тег 'id', який ви присвоюєте своїй кнопці у файлі html / jsp.

2) шлях повного сервлету: шлях, який відображається у браузері, коли ви запускаєте сервлет самостійно


0

Я зробив відображення в web.xml: -

  1. Якщо є інший пакет, створений для нової програми, ми повинні зазначити: -

packagename.filename між відкриттям і закриттям тегу класу сервлетів у файлі xml.

  1. Якщо ви зіставляєте свої файли у форматі xml, але вони не працюють або відображають помилки, тоді коментуйте рядок коду анотації у відповідних файлах.

Обидва методи не працюють один з одним, тому або я використовую метод анотації файлів, згаданих при створенні сервлета, або спосіб зіставлення, тоді я видаляю або коментую рядок анотації. Наприклад:

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

Коментування рядка анотації коду у відповідному файлі, якщо виконано зіставлення у xml.

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

0

Якщо тут хтось, хто використовує MySQL, і відчував, що код працював попереднього дня, а зараз він не працює, то, мабуть, ви повинні відкрити MySQL CLI або MySQL Workbench і просто зробити підключення до бази даних один раз. Після підключення база даних також підключається до програми Java. Раніше я отримував помилку Hibernate Dialect, повідомляючи про щось не так із com.mysql.jdbc.Driver. Я думаю, що на деяких комп’ютерах MySQL має проблеми із запуском. Це вирішено для мене.


-1

Будь ласка, перевірте кореневий контекст не може бути порожнім .

Якщо ви використовуєте eclipse:
клацніть правою кнопкою миші , виберіть властивості , а потім налаштування веб-проекту . Перевірте, щоб кореневий контекст не міг бути порожнім

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.