1. Введение
В этой статье будет представлен обзор того, как зарегистрировать сервлет в Jakarta EE и Spring Boot. В частности, мы рассмотрим два способа регистрации сервлета Java в Jakarta EE — один с использованием файла web.xml
, а другой с помощью аннотаций. Затем мы зарегистрируем сервлеты в Spring Boot, используя конфигурацию XML, конфигурацию Java и настраиваемые свойства.
Отличную вводную статью о сервлетах можно найти здесь .
2. Регистрация сервлетов в Jakarta EE
Давайте рассмотрим два способа регистрации сервлета в Jakarta EE. Во-первых, мы можем зарегистрировать сервлет через web.xml
. В качестве альтернативы мы можем использовать аннотацию Jakarta EE @WebServlet
.
2.1. Через web.xml
Самый распространенный способ зарегистрировать сервлет в приложении Jakarta EE — добавить его в файл web.xml
:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Example</servlet-name>
<servlet-class>com.foreach.Example</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Example</servlet-name>
<url-pattern>/Example</url-pattern>
</servlet-mapping>
Как видите, это включает в себя два шага: (1) добавление нашего сервлета в тег сервлета
, обязательно указав также исходный путь к классу, в котором находится сервлет, и (2) указание URL-адреса, по которому будет отображаться сервлет. в теге url-pattern .
Файл web.xml
Jakarta EE обычно находится в папке WebContent/WEB-INF
.
2.2. Через аннотации
Теперь давайте зарегистрируем наш сервлет, используя аннотацию @WebServlet
в нашем пользовательском классе сервлета. Это устраняет необходимость сопоставления сервлетов в server.xml
и регистрации сервлета в web.xml
:
@WebServlet(
name = "AnnotationExample",
description = "Example Servlet Using Annotations",
urlPatterns = {"/AnnotationExample"}
)
public class Example extends HttpServlet {
@Override
protected void doGet(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<p>Hello World!</p>");
}
}
Приведенный выше код демонстрирует, как добавить эту аннотацию непосредственно в сервлет. Сервлет по-прежнему будет доступен по тому же URL-адресу, что и раньше.
3. Регистрация сервлетов в Spring Boot
Теперь, когда мы показали, как регистрировать сервлеты в Jakarta EE, давайте рассмотрим несколько способов регистрации сервлетов в приложении Spring Boot.
3.1. Программная регистрация
Spring Boot поддерживает 100% программную настройку веб-приложения.
Во-первых, мы реализуем интерфейс WebApplicationInitializer
, а затем реализуем интерфейс WebMvcConfigurer
, который позволяет вам переопределять предустановленные значения по умолчанию вместо того, чтобы указывать каждый конкретный параметр конфигурации, экономя ваше время и позволяя вам работать с несколькими проверенными и реальными настройками вне -коробка.
Давайте посмотрим на пример реализации WebApplicationInitializer
:
public class WebAppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx
= new AnnotationConfigWebApplicationContext();
ctx.register(WebMvcConfigure.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcherExample", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
Далее реализуем интерфейс WebMvcConfigurer
:
@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {
@Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver
= new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/").setCachePeriod(3600)
.resourceChain(true).addResolver(new PathResourceResolver());
}
}
Выше мы явно указываем некоторые параметры по умолчанию для сервлетов JSP, чтобы поддерживать представления .jsp
и обслуживание статических ресурсов.
3.2. XML-конфигурация
Другой способ настроить и зарегистрировать сервлеты в Spring Boot — через web.xml
:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Файл web.xml
, используемый для указания конфигурации в Spring, аналогичен тому, что находится в Jakarta EE. Выше вы можете увидеть, как мы указываем еще несколько параметров через атрибуты под тегом сервлета .
Здесь мы используем другой XML для завершения настройки:
<beans ...>
<context:component-scan base-package="com.foreach"/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Помните, что ваш Spring web.xml
обычно находится в src/main/webapp/WEB-INF
.
3.3. Объединение XML и программной регистрации
Давайте смешаем подход к конфигурации XML с программной конфигурацией Spring:
public void onStartup(ServletContext container) throws ServletException {
XmlWebApplicationContext xctx = new XmlWebApplicationContext();
xctx.setConfigLocation('classpath:/context.xml');
xctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
Давайте также настроим сервлет диспетчера:
<beans ...>
<context:component-scan base-package="com.foreach"/>
<bean class="com.foreach.configuration.WebAppInitializer"/>
</beans>
3.4. Регистрация Бином
Мы также можем программно настроить и зарегистрировать наши сервлеты, используя ServletRegistrationBean
. Ниже мы сделаем это, чтобы зарегистрировать HttpServlet
(который реализует интерфейс javax.servlet.Servlet ):
@Bean
public ServletRegistrationBean exampleServletBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(
new CustomServlet(), "/exampleServlet/*");
bean.setLoadOnStartup(1);
return bean;
}
Основное преимущество этого подхода заключается в том, что он позволяет добавлять в приложение Spring как несколько сервлетов, так и различные типы сервлетов.
Вместо простого использования DispatcherServlet,
который является более специфическим типом HttpServlet
и наиболее распространенным типом, используемым в программном подходе WebApplicationInitializer
к настройке, который мы рассмотрели в разделе 3.1, мы будем использовать более простой экземпляр подкласса HttpServlet
, который предоставляет четыре основные операции HttpRequest
. через четыре функции: doGet()
, doPost()
, doPut()
и doDelete()
, как в Jakarta EE.
Помните, что HttpServlet — это абстрактный класс (поэтому его нельзя создать). Однако мы можем легко создать пользовательское расширение:
public class CustomServlet extends HttpServlet{
...
}
4. Регистрация сервлетов со свойствами
Другой, хотя и необычный, способ настроить и зарегистрировать сервлеты — использовать настраиваемый файл свойств, загруженный в приложение через объект экземпляра PropertyLoader, PropertySource
или PropertySources
.
Это обеспечивает промежуточный вид конфигурации и возможность другой настройки application.properties
, что обеспечивает небольшую непосредственную настройку для невстроенных сервлетов.
4.1. Подход к системным свойствам
Мы можем добавить некоторые пользовательские настройки в наш файл application.properties
или другой файл свойств. Давайте добавим несколько настроек для настройки нашего DispatcherServlet
:
servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL
Давайте загрузим наши пользовательские свойства в наше приложение:
System.setProperty("custom.config.location", "classpath:custom.properties");
И теперь мы можем получить доступ к этим свойствам через:
System.getProperty("custom.config.location");
4.2. Подход к пользовательским свойствам
Начнем с файла custom.properties
:
servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL
Затем мы можем использовать заурядный загрузчик свойств:
public Properties getProperties(String file) throws IOException {
Properties prop = new Properties();
InputStream input = null;
input = getClass().getResourceAsStream(file);
prop.load(input);
if (input != null) {
input.close();
}
return prop;
}
И теперь мы можем добавить эти пользовательские свойства в качестве констант в нашу реализацию WebApplicationInitializer
:
private static final PropertyLoader pl = new PropertyLoader();
private static final Properties springProps
= pl.getProperties("custom_spring.properties");
public static final String SERVLET_NAME
= springProps.getProperty("servlet.name");
public static final String SERVLET_MAPPING
= springProps.getProperty("servlet.mapping");
Затем мы можем использовать их, например, для настройки нашего диспетчерского сервлета:
ServletRegistration.Dynamic servlet = container.addServlet(
SERVLET_NAME, new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping(SERVLET_MAPPING);
Преимущество этого подхода заключается в отсутствии обслуживания XML
-файлов, но с легко изменяемыми параметрами конфигурации, которые не требуют повторного развертывания кодовой базы.
4.3. Подход PropertySource
_
Более быстрый способ сделать это — использовать Spring PropertySource
, который позволяет получить доступ к файлу конфигурации и загрузить его.
PropertyResolver
— это интерфейс, реализованный ConfigurableEnvironment,
который делает свойства приложения доступными при запуске и инициализации сервлета:
@Configuration
@PropertySource("classpath:/com/yourapp/custom.properties")
public class ExampleCustomConfig {
@Autowired
ConfigurableEnvironment env;
public String getProperty(String key) {
return env.getProperty(key);
}
}
Выше мы автоматически подключаем зависимость к классу и указываем расположение нашего файла пользовательских свойств. Затем мы можем получить наше существенное свойство, вызвав функцию getProperty()
, передав значение String.
4.4. Программный подход PropertySource
Мы можем комбинировать описанный выше подход (который включает в себя выборку значений свойств) с подходом ниже (который позволяет нам программно указывать эти значения):
ConfigurableEnvironment env = new StandardEnvironment();
MutablePropertySources props = env.getPropertySources();
Map map = new HashMap(); map.put("key", "value");
props.addFirst(new MapPropertySource("Map", map));
Мы создали карту, связывающую ключ со значением, а затем добавим эту карту в PropertySources
, что позволит вызывать вызовы по мере необходимости.
5. Регистрация встроенных сервлетов
Наконец, мы также рассмотрим базовую настройку и регистрацию встроенных сервлетов в Spring Boot.
Встроенный сервлет обеспечивает полную функциональность веб-контейнера (Tomcat, Jetty и т. д.) без необходимости отдельной установки или обслуживания веб-контейнера .
Вы можете безболезненно, компактно и быстро добавить необходимые зависимости и конфигурацию для простого развертывания живого сервера везде, где такая функциональность поддерживается.
Мы рассмотрим только то, как сделать этот Tomcat, но тот же подход можно использовать для Jetty и альтернатив.
Давайте укажем зависимость для встроенного веб-контейнера Tomcat 8 в pom.xml
:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.11</version>
</dependency>
Теперь давайте добавим теги, необходимые для успешного добавления Tomcat в .war
, созданный Maven во время сборки:
<build>
<finalName>embeddedTomcatExample</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.0.0</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>launch.Main</mainClass>
<name>webapp</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Если вы используете Spring Boot, вместо этого вы можете добавить зависимость spring-boot-starter-tomcat
Spring к вашему pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
5.1. Регистрация через свойства
Spring Boot поддерживает настройку большинства возможных параметров Spring через application.properties
. После добавления необходимых встроенных зависимостей сервлета в ваш pom.xml
вы можете настроить и настроить встроенный сервлет, используя несколько таких параметров конфигурации:
server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet
server.jsp-servlet.registered=true
server.port=8080
server.servlet-path=/
Выше приведены некоторые параметры приложения, которые можно использовать для настройки DispatcherServlet
и совместного использования статических ресурсов. Также доступны настройки для встроенных сервлетов, поддержки SSL и сеансов.
Параметров конфигурации действительно слишком много, чтобы перечислять их здесь, но вы можете увидеть полный список в документации Spring Boot .
5.2. Конфигурация через YAML
Точно так же мы можем настроить наш встроенный контейнер сервлетов, используя YAML. Это требует использования специализированного загрузчика свойств YAML — YamlPropertySourceLoader
— который предоставляет наш YAML и делает его ключи и значения доступными для использования в нашем приложении.
YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
PropertySource<?> yamlProps = sourceLoader.load("yamlProps", resource, null);
5.3. Программная настройка через TomcatEmbeddedServletContainerFactory
Программная конфигурация встроенного контейнера сервлетов возможна через подкласс экземпляра EmbeddedServletContainerFactory
. Например, вы можете использовать TomcatEmbeddedServletContainerFactory
для настройки встроенного сервлета Tomcat.
TomcatEmbeddedServletContainerFactory является оболочкой объекта
org.apache.catalina.startup.Tomcat
, предоставляя дополнительные параметры конфигурации:
@Bean
public ConfigurableServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcatContainerFactory
= new TomcatServletWebServerFactory();
return tomcatContainerFactory;
}
Затем мы можем настроить возвращаемый экземпляр:
tomcatContainerFactory.setPort(9000);
tomcatContainerFactory.setContextPath("/springboottomcatexample");
Каждую из этих конкретных настроек можно настроить с помощью любого из методов, описанных ранее.
Мы также можем напрямую обращаться к объекту org.apache.catalina.startup.Tomcat
и управлять им :
Tomcat tomcat = new Tomcat();
tomcat.setPort(port);
tomcat.setContextPath("/springboottomcatexample");
tomcat.start();
6. Заключение
В этой статье мы рассмотрели несколько способов регистрации сервлета в приложении Jakarta EE и Spring Boot.
Исходный код, используемый в этом руководстве, доступен в проекте Github .