Java Servlet 404 ошибка
Пытаюсь запустить сервлет на tomcat 10.0 и получаю 404-ю ошибку, хотя вроде бы всё делаю правильно.
(tomcat установлен в /opt/tomcat/)
Порядок был такой:
- в
/opt/tomcat/conf/server.xmlдобавил виртуальный хост под локалхостом: servlet.loc
<Host
name="servlet.loc"
appBase="/var/www/tomcat/servlet.loc"
unpackWARs="true"
autoDeploy="true"
/>
- Создал в папке
/var/www/tomcat/servlet.locфайлROOT/WEB-INF/web.xmlсо следующим содержанием:
<?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>
- Создал
/var/www/tomcat/servlet.loc/ROOT/index.htmlс hello world - Прописал в
/etc/hostsстроку127.0.0.1 servlet.loc www.servlet.loc - Зашёл в браузере на
servlet.loc:8080убедился что HW работает - Создал файл
/var/www/tomcat/servlet.loc/subdir/index.htmlс hello world - Зашёл в браузере на
servlet.loc:8080/subdirи так же убедился что HW работает - Создал в InteliJ IDEA Maven-проект со следующим
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>loc.vhosts</groupId>
<artifactId>servlet</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<directory>/var/www/tomcat/servlet.loc/ROOT/WEB-INF/</directory>
</build>
</project>
- Создал класс
src/main/java/HelloServlet.javaсо следующим содержанием:
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet (HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.getWriter().write("hello servlet response");
}
}
- Изменил
ROOT/WEB-INF/web.xmlна следующее содержание:
<?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">
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Собрал проект с помощью maven и убедился что файл
ROOT/WEB-INF/classes/HelloServlet.classсоздалсяПерезапустил tomcat командой
service tomcat restartи проверилservlet.loc:8080/hello
Тут я и получаю 404-ю ошибку от браузера
Что я пытался делать:
- Перенес папку WEB-INF в корневую директорию виртуального хоста (/var/www/tomcat/servlet.loc) и удалил папку ROOT но это не сработало
- Пытался посмотреть логи ошибок но похоже я не смог найти где они могут записываться
- Переделал 10 раз всё заново по гайдам разного разлива из интернета, но всё равно получаю упрямо 404.
Прошу помочь, такое ощущение что не замечаю жирный косяк прямо под носом, но по идее всё должно работать! А так же подсказать где можно почитать про требования к файловой структуре сайтов на java и назначении xml-файлов внутри. Например, сколько должно быть папок WEB-INF? в каждой субдиректории или только в одной, какие должны быть конфиг-файлы, зачем и тд.
Ответы (1 шт):
Итак! Проблема решена. Излагаю последовательность действий.
- Я удалил tomcat 10.0 и установил tomcat 9.0.31
- Я понял на примере localhost что в директории хоста есть только одна папка ROOT, отвечающая за корень сайта и в ней может быть папка WEB-INF/classes, но! внутри субдиректорий не должно быть папок ROOT достаточно сразу localhost/subdir/WEB-INF/classes - в такой субдиректории я поместил скомпилированный сервлет HelloServlet.class и в папке WEB-INF я разместил файл web.xml с содержанием:
<?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">
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Зайдя по ссылке localhost:8080/subdir/hello я убедился что сервлет работает, но! я почти уверен что на tomcat 10.0 такое уже давало ошибку 404, я не могу точно сказать что проблема именно в версии, но меня не покидает чувство что коренным образом поведение обусловлено неправильно выставленными настройками где-то в конфигах или переменных окружения.
Затем я отказался от идеи разместить домашнюю папку за пределами /opt/tomcat, потому что похоже что у tomcat с этим проблемы, так же на уровне конфигурации. Поэтому домашняя папка хоста стала /opt/tomcat/servlet
В server.xml я внес правки добавив виртуальный хост по образу и подобию localhost:
<Host name="servlet.loc" appBase="servlet" unpackWARs="true" autoDeploy="true">
<Valve
className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="servlet_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b"
/>
<Context path="" reloadable="true" />
</Host>
Только я добавил ещё тег Context с атрибутом reloadable="true", эта настройка позволяет tomcat следить за изменением сервлетов без перезагрузки сервера.
Так же я как и в прошлом случае добавил servlet.loc в свой /etc/hosts что бы можно было зайти из браузера
Затем я скомпилировал в папку /opt/tomcat/servlet/ROOT/WEB-INF/classes сервлет с HelloWorld из моего вопроса и в папку WEB-INF положил так же из вопроса web.xml.
После перезагрузки сервера всё заработало.
Надеюсь что это кому-то поможет в будущем. Спасибо всем, кто смотрел на этот вопрос и пытался прикинуть решение.
Если есть у кого идеи, что почитать по администрированию tomcat или в целом советы в направлении упреждения подобных проблем - пожалуйста дайте знать.
