3.11.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.
Если контекст приложения − /app, и сервлет регистрируется с маппингом myservlet, он будет доступен по адресу /app/myservlet.
Более сложный пример использования бина ServletRegistrationManager приведён в разделе Регистрация DispatcherServlet из компонента приложения.