Перейти к основному содержимому

Веб-приложение Java без web.xml

· 4 мин. чтения

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.