Как зарегистрировать сервлет в Java

** 1. Вступление

**

Эта статья предоставит обзор того, как зарегистрировать сервлет в Java EE и Spring Boot. В частности, мы рассмотрим два способа регистрации сервлета Java в Java EE - один с использованием файла web.xml , а другой с использованием аннотаций. Затем мы зарегистрируем сервлеты в Spring Boot, используя конфигурацию XML, конфигурацию Java и настраиваемые свойства.

Отличную вводную статью о сервлетах можно найти по ссылке:/intro-to-servlets[здесь].

2. Регистрация сервлетов в Java EE

Давайте рассмотрим два способа регистрации сервлета в Java EE. Во-первых, мы можем зарегистрировать сервлет через web.xml . В качестве альтернативы мы можем использовать аннотацию Java EE @ WebServlet .

2.1. Через web.xml

Самый распространенный способ регистрации сервлета в приложении Java 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.baeldung.Example</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Example</servlet-name>
    <url-pattern>/Example</url-pattern>
</servlet-mapping>

Как вы можете видеть, это включает в себя два шага: (1) добавление нашего сервлета в тег servlet , убедитесь, что вы также указали исходный путь к классу, в котором находится сервлет, и (2) указание пути URL, который будет открыт сервлету. в теге url-pattern .

Файл Java EE web.xml обычно находится в 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

Теперь, когда мы показали, как регистрировать сервлеты в Java 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, аналогичен тому, который есть в Java EE. Выше вы можете увидеть, как мы указываем еще несколько параметров через атрибуты под тегом servlet .

Здесь мы используем другой XML для завершения настройки:

<beans ...>

    <context:component-scan base-package="com.baeldung"/>

    <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.baeldung"/>
    <bean class="com.baeldung.configuration.WebAppInitializer"/>
</beans>

3.4. Регистрация от Bean

Мы также можем программно настроить и зарегистрировать наши сервлеты, используя 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 () __, как в Java 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

Более быстрый способ выполнить вышесказанное - использовать PropertySource в Spring, который позволяет получить доступ к файлу конфигурации и загрузить его.

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 и сессий.

Здесь слишком много параметров конфигурации, чтобы перечислить их, но вы можете увидеть полный список в https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html[Spring Загрузочная документация.

====  **  5.2. Конфигурация через YAML **

Точно так же мы можем настроить наш встроенный контейнер сервлетов, используя YAML.

Это требует использования специализированного загрузчика свойств YAML - __YamlPropertySourceLoader__ - который предоставляет наш YAML и делает ключи и значения в нем доступными для использования в нашем приложении.

[source,java,gutter:,true]

YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader(); PropertySource<?> yamlProps = sourceLoader.load("yamlProps", resource, null);

====  **  5.3. Программная настройка через TomcatEmbeddedServletContainerFactory **

Программная конфигурация встроенного контейнера сервлета возможна через вложенный класс __EmbeddedServletContainerFactory__. Например, вы можете использовать __TomcatEmbeddedServletContainerFactory__ для настройки встроенного сервлета Tomcat.

__TomcatEmbeddedServletContainerFactory__ оборачивает объект __org.apache.catalina.startup.Tomcat__, предоставляя дополнительные параметры конфигурации:

[source,java,gutter:,true]

@Bean public ConfigurableServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcatContainerFactory = new TomcatServletWebServerFactory(); return tomcatContainerFactory; }

Затем мы можем настроить возвращенный экземпляр:

[source,java,gutter:,true]

tomcatContainerFactory.setPort(9000); tomcatContainerFactory.setContextPath("/springboottomcatexample");

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

Мы также можем напрямую обращаться к объекту __org.apache.catalina.startup.Tomcat__ и манипулировать им:

[source,java,gutter:,true]

Tomcat tomcat = new Tomcat(); tomcat.setPort(port); tomcat.setContextPath("/springboottomcatexample"); tomcat.start();

===  **  6. Заключение**

В этой статье мы рассмотрели несколько способов **  регистрации сервлета в приложении Java EE и Spring Boot. **

Исходный код, используемый в этом руководстве, доступен в проекте https://github.com/eugenp/tutorials/tree/master/spring-boot[Github].