1. 序章

この記事では、 JakartaEEとSpringBootにサーブレットを登録する方法の概要を説明します。具体的には、JavaサーブレットをJakartaEEに登録する2つの方法を見ていきます。1つはWebを使用します。 xml ファイル、および注釈を使用するその他のファイル。 次に、XML構成、Java構成、および構成可能なプロパティを使用して、サーブレットをSpring Bootに登録します。

サーブレットに関する優れた入門記事は、ここにあります。

2. JakartaEEへのサーブレットの登録

JakartaEEにサーブレットを登録する2つの方法を見てみましょう。 まず、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.baeldung.Example</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Example</servlet-name>
    <url-pattern>/Example</url-pattern>
</servlet-mapping>

ご覧のとおり、これには2つのステップが含まれます。(1)サーブレットを servlet タグに追加し、サーブレットが存在するクラスへのソースパスも指定するようにします。(2)URLを指定します。 url-patternタグでサーブレットが公開されるパス。

Jakarta 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. SpringBootへのサーブレットの登録

Jakarta EEにサーブレットを登録する方法を示したので、Spring Bootアプリケーションにサーブレットを登録するいくつかの方法を見てみましょう。

3.1. プログラムによる登録

Spring Bootは、Webアプリケーションの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>

Springで構成を指定するために使用されるweb.xmlは、JakartaEEで見られるものと似ています。 上記では、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 サブクラスインスタンスを使用して、4つの関数 doGet() doPost()を介して4つの基本的なHttpRequest操作を公開します。 doPut()、および doDelete()は、JakartaEEと同じです。

HttpServletは抽象クラスであることに注意してください(したがって、インスタンス化することはできません)。 ただし、カスタム拡張機能を簡単に作成できます。

public class CustomServlet extends HttpServlet{
    ...
}

4. プロパティを使用したサーブレットの登録

サーブレットを構成および登録するもう1つの方法は、 PropertyLoader、PropertySource、またはPropertySourcesインスタンスオブジェクトを介してアプリにロードされたカスタムプロパティファイルを使用することです。[ X220X]

これにより、中間的な種類の構成と、 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()を呼び出して文字列値を渡すことにより、顕著なプロパティをフェッチできます。

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内の組み込みサーブレットの基本的な構成と登録についても見ていきます。

組み込みサーブレットは、Webコンテナを個別にインストールまたは保守することなく完全なWebコンテナ(Tomcat、Jettyなど)機能を提供します

このような機能が簡単に、コンパクトに、そして迅速にサポートされる場合はいつでも、単純なライブサーバー展開に必要な依存関係と構成を追加できます。

このTomcatの実行方法のみを見ていきますが、Jettyやその他の方法でも同じアプローチをとることができます。

pom.xmlで埋め込まれたTomcat8Webコンテナの依存関係を指定しましょう。

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
     <artifactId>tomcat-embed-core</artifactId>
     <version>8.5.11</version>
</dependency>

次に、ビルド時にMavenによって生成された.warにTomcatを正常に追加するために必要なタグを追加しましょう。

<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の spring-boot-starter-tomcat依存関係をpom.xmlに追加できます。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

5.1. プロパティによる登録

Spring Bootは、application.propertiesを介して可能なほとんどのSpring設定の構成をサポートします。 必要な組み込みサーブレットの依存関係を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サポート、およびセッションの設定も利用できます。

ここにリストするには構成パラメーターが多すぎますが、完全なリストはSpringBootのドキュメントで確認できます。

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. 結論

この記事では、JakartaEEおよびSpring Bootアプリケーションにサーブレットを登録するいくつかの方法を確認しました。

このチュートリアルで使用されているソースコードは、Githubプロジェクトで入手できます。