1. Обзор
В этом руководстве мы создаем веб-приложение Java с использованием Servlet 3.0+ .
Мы рассмотрим три аннотации — @WebServlet
, @WebFilter
и @WebListener
— которые могут помочь нам удалить наши файлы web.xml .
2. Зависимость от Maven
Чтобы использовать эти новые аннотации, нам нужно включить зависимость javax.servlet-api :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
3. Конфигурация на основе XML
До Servlet 3.0 мы настраивали веб-приложение Java в файле web.xml
:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<listener>
<listener-class>com.foreach.servlets3.web.listeners.RequestListener</listener-class>
</listener>
<servlet>
<servlet-name>uppercaseServlet</servlet-name>
<servlet-class>com.foreach.servlets3.web.servlets.UppercaseServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uppercaseServlet</servlet-name>
<url-pattern>/uppercase</url-pattern>
</servlet-mapping>
<filter>
<filter-name>emptyParamFilter</filter-name>
<filter-class>com.foreach.servlets3.web.filters.EmptyParamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>emptyParamFilter</filter-name>
<url-pattern>/uppercase</url-pattern>
</filter-mapping>
</web-app>
Давайте начнем заменять каждый раздел конфигурации соответствующими аннотациями, представленными в Servlet 3.0.
4. Сервлеты
JEE 6 поставляется с Servlet 3.0, который позволяет нам использовать аннотации для определений сервлетов, сводя к минимуму использование файла web.xml
для веб-приложения.
Например, мы можем определить сервлет и предоставить его с помощью аннотации @WebServlet.
Давайте определим один сервлет для шаблона URL /uppercase
. Он преобразует значение входного
параметра запроса в верхний регистр:
@WebServlet(urlPatterns = "/uppercase", name = "uppercaseServlet")
public class UppercaseServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String inputString = request.getParameter("input").toUpperCase();
PrintWriter out = response.getWriter();
out.println(inputString);
}
}
Обратите внимание, что мы определили имя для сервлета ( uppercaseServlet)
, на которое теперь можно ссылаться. Мы воспользуемся этим в следующем разделе.
С помощью аннотации @WebServlet
мы заменяем разделы сервлета
и сопоставления сервлетов
из файла web.xml
.
5. Фильтры
Фильтр — это объект, используемый для перехвата запросов или ответов, выполнения задач предварительной или последующей
обработки.
Мы можем определить фильтр с помощью аннотации @WebFilter
.
Давайте создадим фильтр для проверки наличия входного
параметра запроса:
@WebFilter(urlPatterns = "/uppercase")
public class EmptyParamFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
String inputString = servletRequest.getParameter("input");
if (inputString != null && inputString.matches("[A-Za-z0-9]+")) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
servletResponse.getWriter().println("Missing input parameter");
}
}
// implementations for other methods
}
С помощью аннотации @WebFilter
мы заменяем разделы filter
и filter-mapping
из файла web.xml
.
6. Слушатели
Нам часто нужно запускать действия на основе определенных событий. Тут на помощь приходят слушатели. Эти объекты будут прослушивать событие и выполнять заданное нами поведение.
Как и ранее, мы можем определить слушателя с помощью аннотации @WebListener
.
Давайте создадим прослушиватель, который считает каждый раз, когда мы выполняем запрос к серверу. Мы реализуем ServletRequestListener
, прослушивающий ServletRequestEvent
s:
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent event) {
HttpServletRequest request = (HttpServletRequest)event.getServletRequest();
if (!request.getServletPath().equals("/counter")) {
ServletContext context = event.getServletContext();
context.setAttribute("counter", (int) context.getAttribute("counter") + 1);
}
}
// implementations for other methods
}
Обратите внимание, что мы исключаем запросы к шаблону URL /counter
.
С помощью аннотации @WebListener
мы заменяем раздел слушателя из файла
web.xml
.
7. Создавайте и запускайте
Для тех, кто следит за этим, обратите внимание, что для тестирования мы добавили второй сервлет для конечной точки /counter
, который просто возвращает атрибут контекста сервлета счетчика .
Итак, давайте использовать Tomcat
в качестве сервера приложений.
Если мы используем версию maven-war-plugin
до 3.1.0, нам нужно установить для свойства failOnMissingWebXml
значение false
.
Теперь мы можем развернуть наш файл .war на
Tomcat
и получить доступ к нашим сервлетам.
Давайте попробуем нашу конечную точку /uppercase
:
curl http://localhost:8080/spring-mvc-java/uppercase?input=texttouppercase
TEXTTOUPPERCASE
И мы также должны увидеть, как выглядит наша обработка ошибок:
curl http://localhost:8080/spring-mvc-java/uppercase
Missing input parameter
И напоследок быстрый тест нашего слушателя:
curl http://localhost:8080/spring-mvc-java/counter
Request counter: 2
8. XML все еще нужен
Даже со всеми функциями, представленными в Servlet 3.0, есть несколько случаев использования, когда нам все еще понадобится файл web.xml
, среди них:
- Мы не можем определить порядок фильтров с помощью аннотаций — нам по-прежнему нужен раздел
<filter-mapping>
, если у нас есть несколько фильтров, которые нужно применять в определенном порядке. - Чтобы определить время ожидания сеанса , нам по-прежнему нужно использовать раздел
<session-config> .
- Нам по-прежнему нужен элемент
<security-role>
для авторизации на основе контейнера . - И чтобы указать приветственные файлы, нам все еще понадобится раздел
<welcome-file-list>
Или, Servlet 3.0 также представил некоторую программную поддержку через ServletContainerInitializer
, что также может заполнить некоторые из этих пробелов.
9. Заключение
В этом руководстве мы настроили веб-приложение Java без использования файла web.xml
, используя эквивалентные аннотации.
Как всегда, исходный код этого туториала можно найти на GitHub . Кроме того, на GitHub также можно найти приложение, использующее традиционный файл web.xml .
Чтобы узнать о подходе на основе Spring, перейдите к нашему руководству web.xml и Initializer with Spring.