組み込み Web サーバー

各 Spring Boot Web アプリケーションには、組み込み Web サーバーが含まれています。この機能は、組み込みサーバーの変更方法や組み込みサーバーの構成方法など、多くの使い方の質問につながります。このセクションでは、これらの質問に回答します。

別の Web サーバーを使用する

多くの Spring Boot スターターには、デフォルトの組み込みコンテナーが含まれています。

  • サーブレットスタックアプリケーションの場合、spring-boot-starter-web には spring-boot-starter-tomcat を含めることで Tomcat が含まれますが、代わりに spring-boot-starter-jetty または spring-boot-starter-undertow を使用できます。

  • リアクティブスタックアプリケーションの場合、spring-boot-starter-webflux には spring-boot-starter-reactor-netty を含めることで Reactor Netty が含まれますが、代わりに spring-boot-starter-tomcatspring-boot-starter-jettyspring-boot-starter-undertow を使用できます。

別の HTTP サーバーに切り替えるときは、代わりにデフォルトの依存関係を必要なものと交換する必要があります。このプロセスを支援するために、Spring Boot はサポートされる HTTP サーバーごとに個別のスターターを提供します。

次の Maven の例は、Tomcat を除外し、Spring MVC の Jetty を含める方法を示しています。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<!-- Exclude the Tomcat dependency -->
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

次の Gradle の例では、Spring WebFlux の Reactor Netty の代わりに Undertow を使用するために、必要な依存関係とモジュールの交換を構成 (英語) しています。

dependencies {
	implementation "org.springframework.boot:spring-boot-starter-undertow"
	implementation "org.springframework.boot:spring-boot-starter-webflux"
	modules {
		module("org.springframework.boot:spring-boot-starter-reactor-netty") {
			replacedBy("org.springframework.boot:spring-boot-starter-undertow", "Use Undertow instead of Reactor Netty")
		}
	}
}
WebClient (Javadoc) クラスを使用するには spring-boot-starter-reactor-netty が必要なので、別の HTTP サーバーを組み込む必要がある場合でも、Netty への依存関係を維持する必要がある場合があります。

Web サーバーの無効化

クラスパスに Web サーバーの起動に必要なビットが含まれている場合、Spring Boot は自動的に Web サーバーを起動します。この動作を無効にするには、次の例に示すように、application.propertiesWebApplicationType (Javadoc) を構成します。

  • プロパティ

  • YAML

spring.main.web-application-type=none
spring:
  main:
    web-application-type: "none"

HTTP ポートを変更する

スタンドアロンアプリケーションでは、メイン HTTP ポートはデフォルトで 8080 に設定されますが、server.port を使用して設定できます (たとえば、application.properties 内またはシステムプロパティとして)。Environment (Javadoc) 値のバインドが緩和されたため、SERVER_PORT も使用できます (たとえば、OS 環境変数として)。

HTTP エンドポイントを完全にオフにして WebApplicationContext (Javadoc) を作成するには、server.port=-1 を使用します (テストではこれが便利な場合があります)。

詳細については、「Spring Boot の機能」セクションの埋め込みサーブレットコンテナーのカスタマイズ、または ServerProperties (Javadoc) クラスを参照してください。

ランダムな未割り当ての HTTP ポートを使用する

(衝突を防ぐために OS ネイティブを使用して)空きポートをスキャンするには、server.port=0 を使用します。

実行時に HTTP ポートを発見する

サーバーが稼働しているポートには、ログ出力から、または WebServer (Javadoc) を介して WebServerApplicationContext (Javadoc) からアクセスできます。これを取得し、初期化されていることを確認する最善の方法は、型 ApplicationListener<WebServerInitializedEvent> の @Bean (Javadoc) を追加し、公開時にコンテナーをイベントから取り出すことです。

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) を使用するテストでは、次の例に示すように、@LocalServerPort (Javadoc) アノテーションを使用して実際のポートをフィールドに挿入することもできます。

  • Java

  • Kotlin

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

	@LocalServerPort
	int port;

	// ...

}
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.server.LocalServerPort

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

	@LocalServerPort
	var port = 0

	// ...

}

@LocalServerPort (Javadoc) は @Value("${local.server.port}") のメタアノテーションです。通常のアプリケーションにポートを挿入しないでください。先ほど見たように、値はコンテナーが初期化された後にのみ設定されます。テストとは異なり、アプリケーションコードのコールバックは早い段階で処理されます (値が実際に使用可能になる前)。

HTTP レスポンス圧縮を有効にする

HTTP レスポンス圧縮は、Jetty、Tomcat、Reactor Netty、および Undertow でサポートされています。次のように、application.properties で有効にできます。

  • プロパティ

  • YAML

server.compression.enabled=true
server:
  compression:
    enabled: true

デフォルトでは、圧縮を実行するには、レスポンスの長さが少なくとも 2048 バイトである必要があります。server.compression.min-response-size プロパティを設定することにより、この動作を構成できます。

デフォルトでは、コンテンツ型が次のいずれかである場合にのみ、レスポンスが圧縮されます。

  • text/html

  • text/xml

  • text/plain

  • text/css

  • text/javascript

  • application/javascript

  • application/json

  • application/xml

server.compression.mime-types プロパティを設定することにより、この動作を構成できます。

SSL を構成する

SSL は、通常は application.properties または application.yaml のさまざまな server.ssl.* プロパティを設定することによって宣言的に構成できます。サポートされているすべてのプロパティの詳細については、Ssl (Javadoc) を参照してください。

次の例は、Java KeyStore ファイルを使用して SSL プロパティを設定する方法を示しています。

  • プロパティ

  • YAML

server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
server:
  port: 8443
  ssl:
    key-store: "classpath:keystore.jks"
    key-store-password: "secret"
    key-password: "another-secret"

上記の例のような構成を使用すると、アプリケーションはポート 8080 でプレーン HTTP コネクターをサポートしなくなります。Spring Boot は、application.properties を介した HTTP コネクターと HTTPS コネクターの両方の構成をサポートしません。両方が必要な場合は、どちらかをプログラムで設定する必要があります。HTTP コネクターはプログラムで簡単に構成できるため、application.properties を使用して HTTPS を構成することをお勧めします。

PEM エンコードされたファイルの使用

Java KeyStore ファイルの代わりに、PEM エンコードされたファイルを使用できます。可能な限り PKCS#8 キーファイルを使用する必要があります。PEM エンコードされた PKCS#8 キーファイルは、-----BEGIN PRIVATE KEY----- または -----BEGIN ENCRYPTED PRIVATE KEY----- ヘッダーで始まります。

PKCS#1 (-----BEGIN RSA PRIVATE KEY-----) や SEC 1 (-----BEGIN EC PRIVATE KEY-----) など、他の形式のファイルがある場合は、OpenSSL を使用して PKCS#8 に変換できます。

openssl pkcs8 -topk8 -nocrypt -in <input file> -out <output file>

次の例は、PEM でエンコードされた証明書と秘密鍵ファイルを使用して SSL プロパティを設定する方法を示しています。

  • プロパティ

  • YAML

server.port=8443
server.ssl.certificate=classpath:my-cert.crt
server.ssl.certificate-private-key=classpath:my-cert.key
server.ssl.trust-certificate=classpath:ca-cert.crt
server:
  port: 8443
  ssl:
    certificate: "classpath:my-cert.crt"
    certificate-private-key: "classpath:my-cert.key"
    trust-certificate: "classpath:ca-cert.crt"

SSL バンドルの使用

あるいは、次の例に示すように、SSL 信頼マテリアルを SSL バンドルで構成し、Web サーバーに適用することもできます。

  • プロパティ

  • YAML

server.port=8443
server.ssl.bundle=example
server:
  port: 8443
  ssl:
    bundle: "example"

server.ssl.bundle プロパティは、server.ssl の個別の Java KeyStore または PEM プロパティオプションと組み合わせることはできません。

バンドルを使用する場合、server.ssl.ciphersserver.ssl.enabled-protocolsserver.ssl.protocol プロパティも無視されます。これらのプロパティは、代わりに spring.ssl.bundle.<type>.<name>.options プロパティを使用して定義する必要があります。

サーバー名表示の構成

Tomcat、Netty、Undertow は、Server Name Indication (SNI) をサポートするために、個々のホスト名に固有の SSL トラストマテリアルを使用するように構成できます。SNI 構成は Jetty ではサポートされていませんが、複数の証明書が提供されている場合、Jetty は SNI を自動的にセットアップ (英語) できます。

webweb-alt1web-alt2 という名前の SSL バンドルが設定されていると仮定すると、次の設定を使用して、各バンドルを組み込み Web サーバーが提供するホスト名に割り当てることができます。

  • プロパティ

  • YAML

server.port=8443
server.ssl.bundle=web
server.ssl.server-name-bundles[0].server-name=alt1.example.com
server.ssl.server-name-bundles[0].bundle=web-alt1
server.ssl.server-name-bundles[1].server-name=alt2.example.com
server.ssl.server-name-bundles[1].bundle=web-alt2
server:
  port: 8443
  ssl:
    bundle: "web"
    server-name-bundles:
      - server-name: "alt1.example.com"
        bundle: "web-alt1"
      - server-name: "alt2.example.com"
        bundle: "web-alt2"

server.ssl.bundle で指定されたバンドルは、デフォルトのホストと、SNI をサポートするすべてのクライアントに使用されます。server.ssl.server-name-bundles が構成されている場合は、このデフォルトのバンドルを構成する必要があります。

HTTP/2 を構成する

server.http2.enabled 構成プロパティを使用して、Spring Boot アプリケーションで HTTP/2 サポートを有効にすることができます。h2 (HTTP/2 over TLS) と h2c (HTTP/2 over TCP) の両方がサポートされています。h2 を使用するには、SSL も有効にする必要があります。SSL が有効でない場合、h2c が使用されます。たとえば、アプリケーションが TLS ターミネーションを実行しているプロキシサーバーの背後で実行されている場合、h2c を使用することができます。

HTTP/2 と Tomcat

Spring Boot は、デフォルトで h2c および h2 をすぐにサポートする Tomcat 10.1.x と共に提供されます。または、ホストオペレーティングシステムにライブラリとその依存関係がインストールされている場合は、h2 サポートに libtcnative を使用できます。

ライブラリディレクトリは、JVM ライブラリパスで使用できるようにする必要があります(まだ使用していない場合)。-Djava.library.path=/usr/local/opt/tomcat-native/lib などの JVM 引数を使用してこれを行うことができます。詳細については、Tomcat の公式ドキュメントを参照してください [Apache] (英語)

Jetty を使用した HTTP/2

HTTP/2 をサポートするには、Jetty に追加の org.eclipse.jetty.http2:jetty-http2-server 依存関係が必要です。h2c を使用するために、他の依存関係は必要ありません。h2 を使用するには、デプロイに応じて、次の依存関係のいずれかを選択する必要もあります。

  • JDK 組み込みサポートを使用するための org.eclipse.jetty:jetty-alpn-java-server 

  • org.eclipse.jetty:jetty-alpn-conscrypt-server と暗号化ライブラリ (英語)

HTTP/2 と Reactor Netty

spring-boot-webflux-starter は、デフォルトで Reactor Netty をサーバーとして使用しています。Reactor Netty は、すぐに h2c と h2 をサポートします。実行時のパフォーマンスを最適化するために、このサーバーはネイティブライブラリで h2 もサポートしています。これを有効にするには、アプリケーションに追加の依存関係が必要です。

Spring Boot は、すべてのプラットフォームのネイティブライブラリを含む io.netty:netty-tcnative-boringssl-static "uber jar" のバージョンを管理します。開発者は、分類子を使用して必要な依存関係のみをインポートすることを選択できます(Netty 公式ドキュメント (英語) を参照)。

Undertow を使用した HTTP/2

Undertow は、すぐに h2c と h2 をサポートします。

Web サーバーを構成する

一般的には、まず利用可能な多くの構成キーの 1 つを使用することを検討し、application.properties または application.yaml ファイルに新しいエントリを追加して Web サーバーをカスタマイズする必要があります。外部プロパティの組み込みオプションを理解するを参照してください。server.* 名前空間はここで非常に役立ち、サーバー固有の機能のために server.tomcat.*server.jetty.* などの名前空間が含まれています。アプリケーションプロパティ設定一覧のリストを参照してください。

前のセクションでは、圧縮、SSL、HTTP/2 などの多くの一般的なユースケースについて説明しました。ただし、ユースケースの構成キーが存在しない場合は、WebServerFactoryCustomizer (Javadoc) を確認する必要があります。このようなコンポーネントを宣言して、選択に関連するサーバーファクトリにアクセスできます。選択したサーバー(Tomcat、Jetty、Reactor Netty、Undertow)および選択した Web スタック(サーブレットまたはリアクティブ)のバリアントを選択する必要があります。

以下の例は、spring-boot-starter-web (サーブレットスタック)を備えた Tomcat の場合です。

  • Java

  • Kotlin

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

	@Override
	public void customize(TomcatServletWebServerFactory factory) {
		// customize the factory here
	}

}
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component

@Component
class MyTomcatWebServerCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory?> {

	override fun customize(factory: TomcatServletWebServerFactory?) {
		// customize the factory here
	}

}
Spring Boot は、そのインフラストラクチャを内部的に使用してサーバーを自動構成します。自動構成された WebServerFactoryCustomizer (Javadoc) Bean の順序は 0 であり、明示的に別の順序が指定されていない限り、ユーザー定義のカスタマイザーよりも先に処理されます。

カスタマイザーを使用して WebServerFactory (Javadoc) にアクセスできるようになると、コネクター、サーバーリソース、サーバー自体などの特定の部分を、サーバー固有の API を使用して構成できるようになります。

さらに、Spring Boot は以下を提供します。

サーバー サーブレットスタック リアクティブスタック

Tomcat

TomcatServletWebServerFactory (Javadoc)

TomcatReactiveWebServerFactory (Javadoc)

Jetty

JettyServletWebServerFactory (Javadoc)

JettyReactiveWebServerFactory (Javadoc)

Undertow

UndertowServletWebServerFactory (Javadoc)

UndertowReactiveWebServerFactory (Javadoc)

Reactor

なし

NettyReactiveWebServerFactory (Javadoc)

最後の手段として、独自の WebServerFactory (Javadoc) Bean を宣言することもできます。これは、Spring Boot によって提供されるものをオーバーライドします。これを行うと、自動構成されたカスタマイザーがカスタムファクトリに引き続き適用されるため、このオプションは慎重に使用してください。

サーブレット、フィルター、リスナーをアプリケーションに追加する

spring-boot-starter-web を使用するサーブレットスタックアプリケーションでは、Servlet (英語) Filter (英語) ServletContextListener (英語) 、サーブレット API でサポートされているその他のリスナーをアプリケーションに追加する方法が 2 つあります。

Spring Bean を使用して、サーブレット、フィルター、リスナーを追加する

Spring Bean を使用して Servlet (英語) Filter (英語) 、またはサーブレット *Listener を追加するには、そのための @Bean (Javadoc) 定義を提供する必要があります。これは、構成または依存関係を注入する場合に非常に便利です。ただし、アプリケーションライフサイクルの非常に早い段階でコンテナーにインストールする必要があるため、他の Bean が多すぎると初期化されないように十分注意する必要があります。(例: Bean を DataSource (標準 Javadoc) または JPA 構成に依存させることはお勧めできません) 初期化時ではなく、最初に使用するときに Bean を遅延初期化することで、このような制限を回避できます。

フィルターとサーブレットの場合、基礎となるコンポーネントの代わりに、またはそれに加えて、FilterRegistrationBean (Javadoc) または ServletRegistrationBean (Javadoc) を追加することで、マッピングと初期化パラメーターを追加することもできます。

フィルター登録で dispatcherType が指定されていない場合は、REQUEST が使用されます。これは、サーブレット仕様のデフォルトのディスパッチャー型と一致します。

他の Spring Bean と同様に、サーブレットフィルター Bean の順序を定義できます。必ずサーブレット、フィルター、リスナーを Spring Bean として登録するセクションを確認してください。

サーブレットまたはフィルターの登録を無効にする

前述のように、Servlet (英語) または Filter (英語) Bean はサーブレットコンテナーに自動的に登録されます。特定の Filter (英語) または Servlet (英語) Bean の登録を無効にするには、次の例に示すように、その登録 Bean を作成し、無効としてマークします。

  • Java

  • Kotlin

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {

	@Bean
	public FilterRegistrationBean<MyFilter> registration(MyFilter filter) {
		FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(filter);
		registration.setEnabled(false);
		return registration;
	}

}
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {

	@Bean
	fun registration(filter: MyFilter): FilterRegistrationBean<MyFilter> {
		val registration = FilterRegistrationBean(filter)
		registration.isEnabled = false
		return registration
	}

}

クラスパススキャンを使用してサーブレット、フィルター、リスナーを追加する

@WebServlet (英語) @WebFilter (英語) @WebListener (英語) アノテーション付きクラスは、@Configuration (Javadoc) クラスに @ServletComponentScan (Javadoc) アノテーションを付け、登録するコンポーネントを含むパッケージを指定することにより、埋め込みサーブレットコンテナーに自動的に登録できます。デフォルトでは、@ServletComponentScan (Javadoc) はアノテーション付きクラスのパッケージからスキャンします。

アクセスログを構成する

アクセスログは、Tomcat、Undertow、Jetty のそれぞれの名前空間を介して構成できます。

たとえば、次の設定は、カスタムパターン [Apache] (英語) で Tomcat へのアクセスを記録します。

  • プロパティ

  • YAML

server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D microseconds)
server:
  tomcat:
    basedir: "my-tomcat"
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D microseconds)"
ログのデフォルトの場所は、Tomcat ベースディレクトリに相対的な logs ディレクトリです。デフォルトでは、logs ディレクトリは一時ディレクトリです。そのため、Tomcat のベースディレクトリを修正するか、ログに絶対パスを使用することができます。上記の例では、ログはアプリケーションの作業ディレクトリに関連する my-tomcat/logs で利用可能です。

次の例に示すように、Undertow のアクセスログは同様の方法で構成できます。

  • プロパティ

  • YAML

server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a %r %s (%D milliseconds)
server.undertow.options.server.record-request-start-time=true
server:
  undertow:
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D milliseconds)"
    options:
      server:
        record-request-start-time: true

アクセスログの有効化とそのパターンの設定に加えて、リクエストの開始時間の記録も有効になっていることに注意してください。これは、アクセスログパターンにレスポンス時間 (%D) を含める場合に必要です。ログは、アプリケーションの作業ディレクトリに相対的な logs ディレクトリに保存されます。server.undertow.accesslog.dir プロパティを設定することで、この場所をカスタマイズできます。

最後に、Jetty のアクセスロギングは次のように構成することもできます。

  • プロパティ

  • YAML

server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log
server:
  jetty:
    accesslog:
      enabled: true
      filename: "/var/log/jetty-access.log"

デフォルトでは、ログは System.err (標準 Javadoc) にリダイレクトされます。詳細については、Jetty のドキュメントを参照してください。

フロントエンドプロキシサーバーの背後で実行する

アプリケーションがプロキシ、ロードバランサー、クラウド内で実行されている場合、リクエスト情報(ホスト、ポート、スキームなど)は途中で変更される可能性があります。アプリケーションは 10.10.10.10:8080 で実行されている可能性がありますが、HTTP クライアントは example.org のみを見るはずです。

RFC7239「転送ヘッダー」 [IETF] (英語) は、Forwarded HTTP ヘッダーを定義します。プロキシはこのヘッダーを使用して、元のリクエストに関する情報を提供できます。これらのヘッダーを読み取り、リンクを作成して HTTP 302 レスポンス、JSON ドキュメント、HTML ページでクライアントに送信するときに、その情報を自動的に使用するようにアプリケーションを構成できます。X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-SslX-Forwarded-Prefix のような非標準のヘッダーもあります。

プロキシが一般的に使用される X-Forwarded-For および X-Forwarded-Proto ヘッダーを追加する場合、server.forward-headers-strategy を NATIVE に設定するだけでサポートできます。このオプションを使用すると、Web サーバー自体がこの機能をネイティブでサポートします。特定のドキュメントを確認して、特定の動作について学ぶことができます。

これでは十分でない場合、Spring Framework はサーブレットスタック用の ForwardedHeaderFilter とリアクティブスタック用の ForwardedHeaderTransformer を提供します。server.forward-headers-strategy を FRAMEWORK に設定することで、アプリケーションでこれらを使用できます。

Tomcat を使用していて、プロキシで SSL を終了している場合は、server.tomcat.redirect-context-root を false に設定する必要があります。これにより、リダイレクトが実行される前に X-Forwarded-Proto ヘッダーを受け入れることができます。
アプリケーションがサポートされている Cloud Platform (Javadoc) で実行される場合、server.forward-headers-strategy プロパティはデフォルトで NATIVE に設定されます。それ以外の場合は、デフォルトで NONE に設定されます。

Tomcat のプロキシ設定をカスタマイズする

Tomcat を使用する場合は、次の例に示すように、「転送された」情報を伝達するために使用されるヘッダーの名前を追加で構成できます。

  • プロパティ

  • YAML

server.tomcat.remoteip.remote-ip-header=x-your-remote-ip-header
server.tomcat.remoteip.protocol-header=x-your-protocol-header
server:
  tomcat:
    remoteip:
      remote-ip-header: "x-your-remote-ip-header"
      protocol-header: "x-your-protocol-header"

また、Tomcat は、信頼される内部プロキシに一致する正規表現で構成されています。デフォルト値については、付録の server.tomcat.remoteip.internal-proxies エントリを参照してください。次の例に示すように、application.properties にエントリを追加することで、バルブの構成をカスタマイズできます。

  • プロパティ

  • YAML

server.tomcat.remoteip.internal-proxies=192\.168\.\d{1,3}\.\d{1,3}
server:
  tomcat:
    remoteip:
      internal-proxies: "192\\.168\\.\\d{1,3}\\.\\d{1,3}"
internal-proxies を空に設定することにより、すべてのプロキシを信頼できます(ただし、運用環境ではそうしないでください)。

自動構成をオフにして (そのためには、server.forward-headers-strategy=NONE を設定)、WebServerFactoryCustomizer (Javadoc) Bean を使用して新しいバルブインスタンスを追加することで、Tomcat の RemoteIpValve [Apache] (英語) の設定を完全に制御できます。

Tomcat で複数のコネクターを有効にする

次の例に示すように、TomcatServletWebServerFactory (Javadoc) Connector [Apache] (英語) を追加して、HTTP コネクターや HTTPS コネクターを含む複数のコネクターを許可することができます。

  • Java

  • Kotlin

import org.apache.catalina.connector.Connector;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyTomcatConfiguration {

	@Bean
	public WebServerFactoryCustomizer<TomcatServletWebServerFactory> connectorCustomizer() {
		return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createConnector());
	}

	private Connector createConnector() {
		Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
		connector.setPort(8081);
		return connector;
	}

}
import org.apache.catalina.connector.Connector
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyTomcatConfiguration {

	@Bean
	fun connectorCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
		return WebServerFactoryCustomizer { tomcat: TomcatServletWebServerFactory ->
			tomcat.addAdditionalTomcatConnectors(
				createConnector()
			)
		}
	}

	private fun createConnector(): Connector {
		val connector = Connector("org.apache.coyote.http11.Http11NioProtocol")
		connector.port = 8081
		return connector
	}

}

Tomcat の MBean レジストリを有効にします

組み込み Tomcat の MBean レジストリはデフォルトで無効になっています。これにより、Tomcat のメモリフットプリントが最小限に抑えられます。たとえば、Tomcat の MBean を使用して、Micrometer がメトリクスを公開できるようにする場合は、次の例に示すように、server.tomcat.mbeanregistry.enabled プロパティを使用する必要があります。

  • プロパティ

  • YAML

server.tomcat.mbeanregistry.enabled=true
server:
  tomcat:
    mbeanregistry:
      enabled: true

Undertow で複数のリスナーを有効にする

次の例に示すように、UndertowServletWebServerFactory (Javadoc) UndertowBuilderCustomizer (Javadoc) を追加し、io.undertow.Undertow.Builder にリスナーを追加します。

  • Java

  • Kotlin

import io.undertow.Undertow.Builder;

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyUndertowConfiguration {

	@Bean
	public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
		return (factory) -> factory.addBuilderCustomizers(this::addHttpListener);
	}

	private Builder addHttpListener(Builder builder) {
		return builder.addHttpListener(8080, "0.0.0.0");
	}

}
import io.undertow.Undertow
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyUndertowConfiguration {

	@Bean
	fun undertowListenerCustomizer(): WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
		return WebServerFactoryCustomizer { factory: UndertowServletWebServerFactory ->
			factory.addBuilderCustomizers(
				UndertowBuilderCustomizer { builder: Undertow.Builder -> addHttpListener(builder) })
		}
	}

	private fun addHttpListener(builder: Undertow.Builder): Undertow.Builder {
		return builder.addHttpListener(8080, "0.0.0.0")
	}

}

@ServerEndpoint を使用して WebSocket エンドポイントを作成する

埋め込みコンテナーを使用する Spring Boot アプリケーションで @ServerEndpoint (英語) を使用する場合は、次の例に示すように、単一の ServerEndpointExporter (Javadoc) @Bean (Javadoc) を宣言する必要があります。

  • Java

  • Kotlin

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration(proxyBeanMethods = false)
public class MyWebSocketConfiguration {

	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
		return new ServerEndpointExporter();
	}

}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.socket.server.standard.ServerEndpointExporter

@Configuration(proxyBeanMethods = false)
class MyWebSocketConfiguration {

	@Bean
	fun serverEndpointExporter(): ServerEndpointExporter {
		return ServerEndpointExporter()
	}

}

前述の例の Bean は、@ServerEndpoint (英語) アノテーションが付けられたすべての Bean を基礎となる WebSocket コンテナーに登録します。スタンドアロンサーブレットコンテナーにデプロイされる場合、このロールはサーブレットコンテナー初期化子によって実行され、ServerEndpointExporter (Javadoc) Bean は必要ありません。