3.10.4. Регистрация сервлетов и фильтров
Чтобы использовать сервлеты и фильтры, настроенные в компоненте приложения, их нужно зарегистрировать программным способом. Обычно сервлеты и фильтры регистрируются в файле web.xml, но файл web.xml
компонента не влияет на приложение, поэтому стандартный способ не подходит.
Для динамической регистрации сервлетов и фильтров используется бин ServletRegistrationManager
: он гарантирует, что при загрузке каждого сервлета будет использован корректный ClassLoader
, и позволяет обращаться к статическим классам, таким как AppContext. Этот бин необходимо использовать для корректной работы компонентов независимо от варианта развёртывания приложения.
Бин ServletRegistrationManager
имеет два метода:
-
createServlet()
- создаёт сервлет указанного класса. Он загружает класс сервлета с нужным экземпляромClassLoader
, который получает из контекста приложения. Таким образом, новый сервлет может использовать статические классы платформы, например,AppContext
или бин Messages. -
createFilter()
- создаёт фильтр аналогично созданию сервлетов.
Для использования этого бина мы рекомендуем создать в компоненте приложения отдельный бин-инициализатор. Этот бин должен содержать слушатели событий ServletContextInitializedEvent и ServletContextDestroyedEvent
.
Пример бина-инициализатора:
@Component
public class WebInitializer {
@Inject
private ServletRegistrationManager servletRegistrationManager;
@EventListener
public void initializeHttpServlet(ServletContextInitializedEvent e) {
Servlet myServlet = servletRegistrationManager.createServlet(
e.getApplicationContext(), "com.demo.comp.MyHttpServlet");
e.getSource().addServlet("my_servlet", myServlet)
.addMapping("/myservlet/*");
}
}
Здесь класс WebInitializer
содержит только один слушатель, который используется для регистрации HTTP-сервлета из компонента приложения в родительском приложении.
Метод createServlet()
принимает контекст приложения, полученный из события ServletContextInitializedEvent
, и полное имя класса HTTP-сервлета. Далее мы регистрируем сервлет по его имени (my_servlet
) и указываем URL, по которому будет доступен сервлет (/myservlet/
). Теперь при подключении этого компонента к другому приложению сервлет MyHttpServlet
будет зарегистрирован сразу после инициализации AppContext
и ServletContext
.
Сервлет регистрируется с маппингом myservlet
и будет доступен по адресу /app/myservlet/
или /app-core/myservlet/
в зависимости от контекста приложения.
Более сложный пример использования бина ServletRegistrationManager
приведён в разделе Регистрация DispatcherServlet из компонента приложения.