Сервлет возвращает "HTTP-статус 404 Запрошенный ресурс (/ сервлет) недоступен"
У меня есть HTML-форма в файле JSP в моем WebContent/jsps
папка. У меня есть класс сервлетов 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 - не найден
Сообщение: / сервлет
Описание. Исходный сервер не нашел текущего представления для целевого ресурса или не хочет раскрыть, что он существует.
Почему это не работает?
19 ответов
Поместите класс сервлета в package
Прежде всего, поместите класс сервлета в Java package
, Вы должны всегда помещать общедоступные Java-классы в пакет, в противном случае они невидимы для классов, которые находятся в пакете, таких как сам сервер. Таким образом вы устраняете потенциальные проблемы, связанные с окружающей средой. Сервлеты без пакетов работают только в определенных комбинациях Tomcat+JDK, и на это никогда не следует полагаться.
В случае "простого" проекта IDE, класс должен быть помещен в его структуру пакета в папке "Java Resources", а не в "WebContent", это для веб-файлов, таких как JSP. Ниже приведен пример структуры папок Eclipse Dynamic Web Project по умолчанию, как видно в представлении Navigator:
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
В случае проекта Maven, класс должен быть помещен в его структуру пакета внутри main/java
и, таким образом, не, например, main/resources
, это для неклассных файлов. Ниже приведен пример структуры папок проекта веб-приложения Maven по умолчанию, представленного в представлении Eclipse Navigator:
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
затем используйте шаблон URL /servlet/*
вместо. См. Также параметры сервлета и пути, такие как /xyz/{value}/test, как отобразить в web.xml?
@WebServlet
работает только на Servlet 3.0 или новее
Для того, чтобы использовать @WebServlet
, вам нужно только убедиться, что ваш web.xml
файл, если таковой имеется (необязательный, начиная с Servlet 3.0), объявляется как соответствующий версии Servlet 3.0+ и, таким образом, не соответствующий, например, версии 2.5 или ниже. Ниже приведен совместимый с Servlet 3.1 (соответствует Tomcat 8+, WildFly 8+, GlassFish 4+ и т. Д.).
<?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>
Или, если вы еще не используете Servlet 3.0+ (не Tomcat 7 или новее, а 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 Status 500
Ошибка создания экземпляра класса сервлета com.example.YourServlet
И найти в журнале сервера java.lang.ClassNotFoundException: com.example.YourServlet
с последующим java.lang.NoClassDefFoundError: com.example.YourServlet
, в свою очередь, следуют javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
,
Простой способ проверить, правильно ли скомпилирован сервлет и помещен в classpath, - позволить инструменту сборки создать файл WAR (например, проект rightclick, Export> WAR-файл в Eclipse), а затем проверить его содержимое с помощью инструмента ZIP. Если класс сервлета отсутствует в /WEB-INF/classes
, тогда проект неправильно настроен или некоторые значения по умолчанию для конфигурации IDE/ проекта были ошибочно возвращены (например, Project > Build Automatics отключен в Eclipse). Если у вас нет подсказки, лучше всего начать с нуля и не трогать настройки конфигурации IDE/ проекта по умолчанию.
Тестирование сервлета индивидуально
При условии, что сервер работает 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, и они просто станут частью значения.
Смотрите также:
- Наша вики-страница сервлетов
- Как вызвать класс сервлета из формы HTML
- doGet и doPost в сервлетах
- Как передать текущий элемент методу Java, нажав гиперссылку или кнопку на странице JSP?
Другие случаи ошибки HTTP Status 404:
- HTTP Status 404 - Servlet [ServletName] is not available
- HTTP Status 404 - The requested resource (/ProjectName/) is not available
- HTTP Status 404 - The requested resource (/) is not available
- JSP in /WEB-INF returns "HTTP Status 404 The requested resource is not available"
- Referencing a resource placed in WEB-INF folder in JSP file returns HTTP 404 on resource
- Браузер не может получить доступ / найти относительные ресурсы, такие как CSS, изображения и ссылки, при вызове сервлета, который пересылает в JSP
Сценарий № 1: вы случайно повторно развернуты из командной строки, когда Tomcat уже запущен.
Краткий ответ: остановите Tomcat, удалите целевую папку, пакет mvn, затем повторно разверните
Сценарий № 2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME.jsp")
Краткий ответ: Проверьте правильность написания имени файла, убедитесь, что регистр правильный.
Сценарий № 3: Исключения класса не найдены (ответ приведен здесь, потому что: Вопрос № 17982240) ( java.lang.ClassNot FoundException для сервлета в tomcat с затмением) (помечен как дубликат и направил меня сюда)
Краткий ответ #3.1: в файле web.xml указан неверный путь к пакету в теге класса сервлетов.
Краткий ответ № 3.2: у файла Java неверный оператор импорта.
Ниже приведена дополнительная информация для сценария № 1:
1: Остановить Tomcat
- Вариант 1: через CTRL+C в терминале.
- Вариант 2: (терминал закрыт, когда кот еще работает)
- ------------ 2.1: нажмите: Windows + R -> введите: " services.msc "
- ------------ 2.2: найдите "Apache Tomcat #.# Tomcat#" в столбце "Имя" списка.
- ------------ 2.3: Правый клик -> " Стоп "
2. Удалите "целевую" папку. (MvN Clean не поможет вам здесь)
3: пакет mvn
4: YOUR_DEPLOYMENT_COMMAND_HERE
(Шахта: java -jar target/dependency/webapp-runner.jar --port 5190 target/*. War)
Full Back Story:
Случайно открыл новое окно git-bash и попытался развернуть.war-файл для моего проекта heroku через:
java -jar target / dependency / webapp-runner.jar --port 5190 target / *. war
После неудачного развертывания я понял, что у меня открыто два окна git-bash, и не использовал CTLR+C, чтобы остановить предыдущее развертывание.
Меня встретили:
HTTP Status 404 - Not Found Тип отчета о состоянии
Сообщение /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:
Вы поместили неправильный оператор " package " в верхней части своего файла myClass.java.
Например:
Файл находится в папке " / my_stuff "
Вы по ошибке пишете:
package com.my_stuff
Это сложно, потому что:
1: сборка maven (пакет mvn) не будет сообщать об ошибках здесь.
2: строка класса сервлета в web.xml может иметь ПРАВИЛЬНЫЙ путь к пакету. Например:
<servlet-class>
my_stuff.MyClass
</servlet-class>
Используемые стеки: Блокнот ++ + GitBash + Maven + Heroku Web App Runner + Tomcat9 + Windows10:
Убедитесь, что вы ввели правильное сопоставление URL-адресов, как указано в Web.xml.
Например:
В web.xml ваше объявление сервлета может быть:
<servlet>
<servlet-name>ControllerA</servlet-name>
<servlet-class>PackageName.ControllerA</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ControllerA</servlet-name>
<url-pattern>/theController</url-pattern>
</servlet-mapping>
Что делает этот фрагмент
<url-pattern>/theController</url-pattern>
задаст имя, которое будет использоваться для вызова сервлета из внешнего интерфейса (например: форма) через URL-адрес. Поэтому, когда вы ссылаетесь на сервлет во внешнем интерфейсе, чтобы гарантировать, что запрос идет к сервлету "ControllerA", он должен ссылаться на указанный шаблон URL-адреса "theController" из формы.
например:
<form action="theController" method="POST">
</form>
Я была такая же проблема. Пробовал все это, но не помогло. Мне удалось решить эту проблему, добавив теги элементов в начало и конец файла xml. Я оставлю свой XML-файл ниже для справки.
<?xml version="1.0" encoding="UTF-8"?>
<element>
<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_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>InsertServlet</servlet-name>
<servlet-class>com.worklog.InsertServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>InsertServlet</servlet-name>
<url-pattern>/insert</url-pattern>
</servlet-mapping>
</web-app>
</element>
Моя проблема заключалась в том, что в моем методе отсутствовала аннотация @RequestBody. После добавления аннотации я больше не получил исключение 404.
Сделайте следующие два шага. Надеюсь, это решит проблему "404 not found" на сервере 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
Я удалил старую веб-библиотеку, такую как библиотеки Spring Framework. И построить новый путь библиотек. Тогда это работает.
Решение для HTTP Status 404
в среде IDE NetBeans: щелкните правой кнопкой мыши свой проект и перейдите к свойствам проекта, затем нажмите "Выполнить" и введите относительный URL-адрес проекта, например index.jsp
,
- Project-> Свойства
- Нажмите на Run
- Относительный URL:/index.jsp (выберите корневой URL вашего проекта)
Отображение в web.xml - это то, что я сделал:-
- Если для новой программы создан другой пакет, мы должны упомянуть:-
packagename.filename между открытием и закрытием тега класса сервлета в XML-файле.
- Если вы сопоставляете свои файлы в 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")
У меня сработало исправление (если вы используете Maven): щелкните правой кнопкой мыши свой проект, Maven -> Обновить проект. Это может привести к другой ошибке с JDK и другими библиотеками (в моем случае с соединителем MySQL), но как только вы их исправите, ваша исходная проблема должна быть исправлена!
Если вы хотите открыть сервлет с помощью 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) полный путь сервлета: путь, который отображается в браузере, когда вы запускаете только сервлет.
Прежде всего, запустите свою IDE от имени администратора. После этого щелкните правой кнопкой мыши папку проекта -> Project Facets и убедитесь, что версия Java установлена правильно. На моем ПК. (Для примера 1.8) Теперь должно работать.
Не запускайте просто свой сервер, например Wildfly, с помощью cmd. Он должен быть запущен в среде IDE и теперь перейти по URL-адресу локального хоста. Пример: http://localhost:8080/HelloWorldServlet/HelloWorld
Старая ветка, но поскольку я не нашел ее в другом месте, вот еще одна возможность:
Если вы используете servlet-api 3.0+, то ваш web.xml НЕ должен включать metadata-complete="true"
атрибут
Это говорит tomcat для отображения сервлетов, используя данные, приведенные в web.xml
вместо использования @WebServlet
аннотаций.
Если здесь есть кто-то, кто использует MySQL и считает, что код работал накануне, а теперь нет, то я думаю, вы должны открыть MySQL CLI или MySQL Workbench и просто один раз подключиться к базе данных. После подключения база данных также подключается к Java-приложению. Раньше я получал ошибку Hibernate Dialect, в которой говорилось, что что-то не так с com.mysql.jdbc.Driver. Я думаю, что у MySQL на некоторых компьютерах проблемы с запуском. Это решило для меня.
Если вы студент и плохо знакомы с Java, возможно, возникла проблема с вашим файлом web.xml.
- Попробуйте удалить файл web.xml.
- Во-вторых, проверьте, правильно ли установлены переменные вашего пути.
- Перезагрузите сервер Tomcat или ваш компьютер.
Ваша проблема обязательно будет решена.
Я тоже столкнулся с этой проблемой, я получал 404 при доступе к шаблону URL, который, как я знал, был связан с сервлетом. Причина в том, что у меня было 2 сервлета с их @WebServlet
name
набор параметров в виде той же строки.
@WebServlet(name = "ServletName", urlPatterns = {"/path"})
public class ServletName extends HttpServlet {}
@WebServlet(name = "ServletName", urlPatterns = {"/other-path"})
public class OtherServletName extends HttpServlet {}
Оба
name
параметры такие же. Если вы используете параметр name, убедитесь, что они уникальны по сравнению со всеми другими сервлетами в вашем приложении.
У меня была такая же проблема. Я разрабатывал REST API на основе mvc, где не было явной конфигурации или файлов html. API использовал Swagger для создания пользовательского интерфейса. Проблема началась, когда я представил Swagger версии 3.0.0. Я вернулся к Swagger "2.9.2". Это решило мою проблему.
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
Пожалуйста, проверьте, что корень контекста не может быть пустым.
Если вы используете затмение:
щелкните правой кнопкой мыши, выберите свойства, затем настройки веб-проекта. Проверьте, что корень контекста не может быть пустым