Статьи

EE Servlet 3: Как настроить Backend Services в веб-приложении

В веб-приложении обеспечение взаимодействия с пользователем (UI) часто составляет только половину работы. Многие приложения имеют требования, которые поддерживаются внутренними службами. Некоторыми примерами серверных служб являются процесс планировщика (пакетная обработка), прослушивание очереди и ответ при поступлении сообщений, или простая вещь, такая как хранение информации для использования всем приложением. Эти глобальные данные часто необходимо разделить между всеми классами сервлетов (для каждого процессора запросов). Здесь я покажу вам, как и где вы должны добавить такие внутренние службы в приложение на основе сервлета.

Прежде чем мы начнем, я хотел бы объяснить, как приложение Servlet хранит переменные данных (в конце концов, бэкэнд-сервисы — это просто объекты Java). Существует 3 основных области, в которых вы можете добавлять и обмениваться данными (мы иногда называем эти области в разных «пространствах», «сферах» или «контекстах»). Вы также можете рассматривать каждую из этих областей как хэш-карту с уникальными ключами и значениями данных.

  1. Область приложения. Это глобальное пространство карты хранения приложения, которое выделено для вашего экземпляра веб-приложения. Каждое веб-приложение будет иметь свое уникальное пространство. Даже если вы развернете один и тот же файл WAR на сервере домена, каждый из них получит свое собственное пространство. Вы можете овладеть этим пространством, реализовав интерфейс javax.servlet.ServletContextListener . Этот интерфейс также имеет два метода обратного вызова, которые будут вызываться при запуске приложения (init) или завершении работы (уничтожить). В этом методе вы можете самостоятельно настроить и очистить логику приложения или службы. Вы можете хранить любые объекты Java с помощью метода ServletContext#setAttribute(key, value) . Это хранилище не является постоянным внешне, а только в памяти сервера. Таким образом, чем больше вы добавляете к нему, тем больше памяти вам понадобится (обычно вы просто хотите хранить ссылки на ваши сервисные объекты, поэтому обычно у вас нет проблем с памятью). Это место, где вы должны создать внутренние службы и инициализировать его, а затем добавить экземпляры в пространство, чтобы вы могли получить его позже.

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

  2. Область запроса — это единое пространство карты хранения процесса HTTP-запроса, выход только для определенного запроса или временного хранилища. Это пространство карты также не является постоянным. У вас будет доступ к этому пространству внутри вашего кода сервлета с помощью одного из методов действия HTTP. Вы добавите данные с помощью метода HttpServletRequest#setAttribute(key, value) . Обычно эти сохраненные данные используются для передачи на уровень обработки VIEW (например, JSP) для создания вывода HTML. Вы уже видели некоторые из моих предварительных сообщений, которые используют это внутри компонента сервлета.

    Также обратите внимание, что внутри метода Servlet, который обрабатывает запрос, у вас также будет доступ к методу пространства приложения, описанному выше, с помощью метода HttpServletRequest#getServletContext()#getAttribute(key) .

  3. Область сеанса — это специальное пространство, где вы можете отслеживать конкретные взаимодействия пользователя с приложением в виде последовательности запросов на диалог или, таким образом, вызывать сеанс пользователя. Помните, что HTTP-запрос не имеет состояния, поэтому вам понадобится это пространство, если вы хотите сохранить некоторые данные для совместного использования несколькими запросами, но они должны быть изолированы для каждого пользователя клиентского браузера. Это обычно используется при реализации входа пользователя в систему и ограничения ресурсов в приложении. Вы можете добавить в это пространство, используя метод HttpServletRequest#getSession(true)#setAttribute(key, value) в классе Serlvet. Сервер application будет автоматически возвращать вам один и тот же объект сеанса или пространство каждый раз для этого конкретного пользователя клиента.

Однако обработка пользовательского сеанса может быть непростой задачей, поэтому вам придется потратить время и тщательно разработать приложение, чтобы реализовать решение, соответствующее вашим потребностям. Я напишу отдельный пост о том, как использовать область действия Session в будущем, но сейчас я могу показать вам пример того, как я инициализирую свое веб-приложение с пользовательскими службами внутри. Вы можете найти этот код в моем примере с сервлетом3 .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package zemian.servlet3example.web;
 
import javax.servlet.ServletContext;
import zemian.servlet3example.service.Application;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import zemian.service.logging.Logger;
 
@WebListener
public class WebAppStartup implements ServletContextListener {
    private static final Logger LOGGER = new Logger(WebAppStartup.class);
 
    @Override
    public void contextInitialized(ServletContextEvent event) {
        LOGGER.debug("WebApp is starting up.");
        Application app = Application.getInstance();
        app.init();
                
        // Store the app instances.        event.getServletContext().setAttribute(Application.SERVLET_CONTEXT_KEY, app);
        LOGGER.info("WebApp initialized.");      
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent event) {
        Application app = Application.getInstance();
        app.destroy();
        LOGGER.info("WebApp destroyed.");
    }
}

Имея это в виду, я могу легко добавить любые пользовательские бизнес-сервисы внутри класса Application , а затем получить доступ к любому из кода сервлета. Обратите внимание, что я использую аннотацию @WebListener Servlet 3, поэтому никакой конфигурации не требуется Вы просто упаковываете свое приложение WAR, и оно будет обнаружено вашим сервером приложений EE!

Ссылка: EE Servlet 3: Как настроить Backend Services в веб-приложении от нашего партнера JCG Земьяна Дена в блоге A Programmer’s Journal .