Параметры инициализации контекста и сервлета

Параметры инициализации контекста и сервлета

1. обзор

Servlets - это простые классы Java, которые выполняются в контейнере сервлетов.

HTTP-сервлеты (определенный тип сервлетов) являются гражданами первого класса в веб-приложениях Java. API HTTP-сервлетов -aimed at handling HTTP requests through the typical request-processing-response cycle, implemented in client-server protocols.

Кроме того, сервлеты могут управлять взаимодействием между клиентом (обычно веб-браузером) и сервером, используя пары ключ-значение в форме параметров запроса / ответа.

Эти параметры могут быть инициализированы и привязаны к области приложения (параметры контекста) и области действия сервлета (параметры сервлета).

В этом руководстве мы изучимhow to define and access context and servlet initialization parameters.

2. Инициализация параметров сервлета

Мы можем определить и инициализировать параметры сервлета, используя аннотации и стандартный дескриптор развертывания - файл“web.xml”. Стоит отметить, что эти два варианта не исключают друг друга.

Давайте подробно рассмотрим каждый из этих вариантов.

2.1. Использование аннотаций

Initializing servlets parameters with annotations allows us to keep configuration and source code in the same place.

В этом разделе мы продемонстрируем, как определять и получать доступ к параметрам инициализации, привязанным к определенному сервлету, с помощью аннотаций.

Для этого мы реализуем простой классUserServlet, который собирает пользовательские данные с помощью простой HTML-формы.

Во-первых, давайте посмотрим на файл JSP, который отображает нашу форму:



    
        Context and Initialization Servlet Parameters
        
    
    
        

Please fill the form below:

Обратите внимание, что мы закодировали атрибут формыaction с помощьюEL (язык выражений). Это позволяет ему всегда указывать на путь“/userServlet”, независимо от расположения файлов приложения на сервере.

Выражение“$\{pageContext.request.contextPath}”sets a dynamic URL for the form, which is always relative to the application’s context path.

Вот наша первоначальная реализация сервлета:

@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={
@WebInitParam(name="name", value="Not provided"),
@WebInitParam(name="email", value="Not provided")}))
public class UserServlet extends HttpServlet {
    // ...

    @Override
    protected void doPost(
      HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {
        processRequest(request, response);
        forwardRequest(request, response, "/WEB-INF/jsp/result.jsp");
    }

    protected void processRequest(
      HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {

        request.setAttribute("name", getRequestParameter(request, "name"));
        request.setAttribute("email", getRequestParameter(request, "email"));
    }

    protected void forwardRequest(
      HttpServletRequest request,
      HttpServletResponse response,
      String path)
      throws ServletException, IOException {
        request.getRequestDispatcher(path).forward(request, response);
    }

    protected String getRequestParameter(
      HttpServletRequest request,
      String name) {
        String param = request.getParameter(name);
        return !param.isEmpty() ? param : getInitParameter(name);
    }
}

В этом случае мы определили два параметра инициализации сервлета,name иemail, с помощьюusing initParams and the @WebInitParam annotations.

Обратите внимание, что мы использовали метод HttpServletRequestgetParameter() для извлечения данных из HTML-формы и методgetInitParameter() для доступа к параметрам инициализации сервлета.

МетодgetRequestParameter() проверяет, являются ли параметры запросаname иemail пустыми строками.

Если они являются пустыми строками, им назначаются значения по умолчанию для соответствующих параметров инициализации.

МетодdoPost() сначала получает имя и адрес электронной почты, которые пользователь ввел в HTML-форму (если есть). Затем он обрабатывает параметры запроса и пересылает запрос в файл“result.jsp”:



    
        
        User Data
    
    
        

User Information

Name: ${name}

Email: ${email}

Если мы развернем наш образец веб-приложения на сервере приложений, таком какApache Tomcat,Oracle GlassFish илиJBoss WidlFly, и запустим его, оно сначала должно отобразить страницу HTML-формы.

После того, как пользователь заполнил поляname иemail и отправил форму, он выведет данные:

User Information
Name: the user's name
Email: the user's email

Если форма просто пуста, она будет отображать параметры инициализации сервлета:

User Information
Name: Not provided
Email: Not provided

В этом примере мы показалиhow to define servlet initialization parameters by using annotations, and how to access them with the getInitParameter() method.

2.2. Использование стандартного дескриптора развертывания

This approach differs from the one that uses annotations, as it allows us to keep configuration and source code isolated from each other.

Чтобы продемонстрировать, как определить параметры сервлета инициализации с помощью файла“web.xml”, давайте сначала удалим аннотацииinitParam и@WebInitParam из классаUserServlet:

@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"})
public class UserServlet extends HttpServlet { ... }

Затем давайте определим параметры инициализации сервлета в файле“web.xml”:



    
        UserServlet
        UserServlet
        
            name
            Not provided
        
        
            email
            Not provided
        
    

Как показано выше, определение параметров инициализации сервлета с использованием файла“web.xml” просто сводится к использованию тегов<init-param>,<param-name> и<param-value>.

Кроме того, можно определить столько параметров сервлета, сколько необходимо, если мы будем придерживаться указанной выше стандартной структуры.

Когда мы повторно внедряем приложение на сервер и перезапускаем его, оно должно вести себя так же, как версия, использующая аннотации.

3. Инициализация параметров контекста

Иногда нам нужно определить некоторые неизменные данные, которые должны быть доступны глобально и доступны через веб-приложение.

Из-за глобального характера данных мы должныuse application-wide context initialization parameters for storing the data, rather than resorting to the servlet counterparts.

Несмотря на то, что невозможно определить параметры инициализации контекста с помощью аннотаций, мы можем сделать это в файле“web.xml”.

Предположим, мы хотим предоставить некоторые глобальные значения по умолчанию для страны и провинции, где работает наше приложение.

Мы можем сделать это с помощью нескольких параметров контекста.

Давайте соответствующим образом реорганизуем файл“web.xml”:


    
        province
        Mendoza
    
    
        country
        Argentina
    
    

На этот раз мы использовали теги<context-param>, <param-name>, и<param-value> для определения параметров контекстаprovince иcountry.

Конечно, нам нужно провести рефакторинг классаUserServlet, чтобы он мог получать эти параметры и передавать их на страницу результатов.

Вот соответствующие разделы сервлета:

@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"})
public class UserServlet extends HttpServlet {
    // ...

    protected void processRequest(
      HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {

        request.setAttribute("name", getRequestParameter(request, "name"));
        request.setAttribute("email", getRequestParameter(request, "email"));
        request.setAttribute("province", getContextParameter("province"));
        request.setAttribute("country", getContextParameter("country"));
    }

    protected String getContextParameter(String name) {-
        return getServletContext().getInitParameter(name);
    }
}

Обратите внимание на реализацию методаgetContextParameter(), которыйfirst gets the servlet context through getServletContext(), and then fetches the context parameter with the getInitParameter() method.

Затем нам нужно реорганизовать файл“result.jsp”, чтобы он мог отображать параметры контекста вместе с параметрами, специфичными для сервлета:

Name: ${name}

Email: ${email}

Province: ${province}

Country: ${country}

Наконец, мы можем повторно развернуть приложение и выполнить его еще раз.

Если пользователь заполняет форму HTML именем и адресом электронной почты, он отображает эти данные вместе с параметрами контекста:

User Information
Name: the user's name
Email: the user's email
Province: Mendoza
Country: Argentina

В противном случае он выведет параметры инициализации сервлета и контекста:

User Information
Name: Not provided
Email: Not provided
Province: Mendoza
Country: Argentina

Хотя пример надуманный, он показываетhow to use context initialization parameters to store immutable global data.

Поскольку данные привязаны к контексту приложения, а не к конкретному сервлету, мы можем получить к ним доступ из одного или нескольких сервлетов, используя методыgetServletContext() иgetInitParameter().

4. Заключение

В этой статьеwe learned the key concepts of context and servlet initialization parameters and how to define them and access them using annotations and the “web.xml” file.

В течение достаточно долгого времени в Java существовала сильная тенденция избавляться от файлов конфигурации XML и по мере возможности переходить на аннотации.

CDI,Spring,Hibernate, и это лишь некоторые из них, являются яркими примерами этого.

Тем не менее, нет ничего плохого в использовании файла“web.xml” для определения контекста и параметров инициализации сервлета.

Несмотря на то, чтоServlet API эволюционировал довольно быстрыми темпами в сторону этой тенденции,we still need to use the deployment descriptor for defining context initialization parameters.

Как обычно, доступны все примеры кода, показанные в этой статьеover on GitHub.