Поместите класс сервлета в package
Прежде всего, поместите класс сервлета в Java package
. Вы всегда должны помещать общедоступные повторно используемые классы Java в пакет, в противном случае они будут невидимы для классов, находящихся в пакете, таких как сам сервер. Таким образом вы устраняете потенциальные проблемы, связанные с окружающей средой. Сервлеты без пакетов работают только в определенных комбинациях Tomcat + JDK, и на это нельзя полагаться.
В случае «простого» проекта IDE класс необходимо поместить в его структуру пакета внутри папки «Java Resources», а не «WebContent», это для веб-файлов, таких как JSP. Ниже приведен пример структуры папок динамического веб-проекта Eclipse по умолчанию в виде навигатора :
EclipseProjectName
|-- src
| `-- com
| `-- example
| `-- YourServlet.java
|-- WebContent
| |-- WEB-INF
| | `-- web.xml
| `-- jsps
| `-- page.jsp
:
В случае проекта Maven класс должен быть помещен в его структуру пакета внутри main/java
и, следовательно, не, например main/resources
, для файлов, не являющихся классами . Ниже приведен пример структуры папок проекта Maven webapp по умолчанию, как видно в представлении 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» отображения сервлета. Это абсолютно не по определению имя класса / имя файла класса сервлета. В качестве значения @WebServlet
аннотации указывается шаблон URL .
package com.example;
@WebServlet("/servlet")
public class YourServlet extends 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 или ниже . Ниже приведен совместимый с Servlet 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"
>
</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>
</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
, за которым следует java.lang.NoClassDefFoundError: com.example.YourServlet
, по очереди, а затем javax.servlet.ServletException: Error instantiating servlet class com.example.YourServlet
.
Простой способ проверить, правильно ли скомпилирован сервлет и помещен в путь к классам, - позволить инструменту сборки создать файл WAR (например, щелчок правой кнопкой мыши, Экспорт> файл WAR в Eclipse), а затем проверить его содержимое с помощью инструмента ZIP. Если класс сервлета отсутствует /WEB-INF/classes
или экспорт вызывает ошибку, значит, проект плохо настроен или некоторые настройки конфигурации IDE / проекта были ошибочно возвращены (например, Project> Build Automatically отключен в 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: вы случайно повторно развернули из командной строки, когда tomcat уже был запущен .
Краткий ответ: остановите Tomcat, удалите целевую папку , пакет mvn, затем повторно разверните
Сценарий № 2: request.getRequestDispatcher (" MIS_SPELLED_FILE_NAME .jsp")
Короткий ответ: Проверьте имя файла орфография , убедитесь случаем является правильным.
Сценарий № 3: Исключения класса не найдены (ответ помещен здесь, потому что: Вопрос № 17982240) ( java.lang.ClassNotFoundException для сервлета в tomcat с eclipse ) (был отмечен как повторяющийся и направил меня сюда)
Краткий ответ № 3.1: web.xml имеет неверный путь к пакету в теге сервлета.
Краткий ответ №3.2: в java-файле неверный оператор импорта.
Ниже приведены дополнительные сведения о сценарии №1:
1: Остановить Tomcat
2: Удалить «целевую» папку. (mvn clean здесь вам не поможет)
3: пакет mvn
4: ВАШЕ_РАЗДЕЛЕНИЕ_COMMAND_HERE
(Мой: 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 для остановки предыдущего развертывания .
Меня встретили:
Ниже приведены дополнительные сведения о сценарии № 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>
источник
Решение для
HTTP Status 404
IDE NetBeans: щелкните свой проект правой кнопкой мыши и перейдите в свойства проекта, затем нажмите «Выполнить», затем введите относительный URL-адрес вашего проекта, напримерindex.jsp
.источник
Моя проблема заключалась в том, что в моем методе отсутствовала аннотация @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. И построим новый путь к библиотекам. Тогда это работает.
источник
Старый поток, но поскольку я не нашел его в другом месте, вот еще одна возможность:
Если вы используете servlet-api 3.0+ , тогда ваш web.xml НЕ должен включать
metadata-complete="true"
атрибутЭто сообщает tomcat о необходимости отображать сервлеты с использованием данных, указанных в,
web.xml
вместо использования@WebServlet
аннотации.источник
Прежде всего, запустите свою IDE от имени администратора. После этого щелкните правой кнопкой мыши папку проекта -> Project Facets и убедитесь, что версия Java установлена правильно. На моем ПК. (Для примера 1.8) Теперь должно работать.
Не запускайте просто свой сервер, например Wildfly, с помощью cmd. Он должен быть запущен в среде IDE и теперь перейти по URL-адресу локального хоста. Пример: http: // localhost: 8080 / HelloWorldServlet / HelloWorld
источник
У меня сработало исправление (если вы используете 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) полный путь сервлета: путь, который отображается в браузере, когда вы запускаете только сервлет.
источник
Отображение в web.xml - это то, что я сделал: -
packagename.filename между открытием и закрытием тега класса сервлета в 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")
источник
Если здесь есть кто-то, кто использует MySQL и считает, что код работал накануне, а теперь нет, то я думаю, вам нужно открыть MySQL CLI или MySQL Workbench и просто один раз подключиться к базе данных. После подключения база данных также подключается к Java-приложению. Раньше я получал ошибку Hibernate Dialect, в которой говорилось, что что-то не так с com.mysql.jdbc.Driver. Я думаю, что у MySQL на некоторых компьютерах проблемы с запуском. Это решило для меня.
источник
Если вы студент и плохо знакомы с Java, возможно, возникла проблема с вашим файлом web.xml.
Ваша проблема обязательно будет решена.
источник
Убедитесь, что корень контекста не может быть пустым .
Если вы используете eclipse:
щелкните правой кнопкой мыши , выберите свойства , затем настройки веб-проекта . Убедитесь, что корень контекста не может быть пустым
источник