WebFlux 構成

WebFlux Java 構成は、アノテーション付きコントローラーまたは関数エンドポイントでリクエストを処理するために必要なコンポーネントを宣言し、構成をカスタマイズするための API を提供します。つまり、Java 構成によって作成された基礎となる Bean を理解する必要はありません。ただし、理解したい場合は、WebFluxConfigurationSupport で表示するか、特別な Bean 型の内容について詳しく読むことができます。

構成 API にはない高度なカスタマイズについては、拡張構成モードを使用して構成を完全に制御できます。

WebFlux 構成の有効化

次の例に示すように、Java config で @EnableWebFlux アノテーションを使用できます。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig {
}
@Configuration
@EnableWebFlux
class WebConfig

前述の例では、多数の Spring WebFlux インフラストラクチャ Bean を登録し、JSON、XML などのクラスパスで利用可能な依存関係に適応します。

WebFlux 構成 API

Java 構成では、次の例に示すように、WebFluxConfigurer インターフェースを実装できます。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	// Implement configuration methods...
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	// Implement configuration methods...
}

変換、フォーマット

デフォルトでは、さまざまな数値および日付型のフォーマッタがインストールされ、フィールドでの @NumberFormat および @DateTimeFormat によるカスタマイズのサポートがインストールされています。

Java config でカスタムフォーマッタとコンバーターを登録するには、次を使用します。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addFormatters(FormatterRegistry registry) {
		// ...
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addFormatters(registry: FormatterRegistry) {
		// ...
	}
}

デフォルトでは、Spring WebFlux は、日付値を解析およびフォーマットするときに、リクエストロケールを考慮します。これは、日付が「入力」フォームフィールドを持つ文字列として表されるフォームで機能します。ただし、「日付」および「時刻」フォームフィールドの場合、ブラウザーは HTML 仕様で定義されている固定形式を使用します。このような場合、日付と時刻のフォーマットは次のようにカスタマイズできます。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addFormatters(FormatterRegistry registry) {
		DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
		registrar.setUseIsoFormat(true);
		registrar.registerFormatters(registry);
     	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addFormatters(registry: FormatterRegistry) {
		val registrar = DateTimeFormatterRegistrar()
		registrar.setUseIsoFormat(true)
		registrar.registerFormatters(registry)
	}
}
FormatterRegistrar 実装をいつ使用するかの詳細については、FormatterRegistrar SPI および FormattingConversionServiceFactoryBean を参照してください。

検証

デフォルトでは、Bean バリデーションがクラスパス (Hibernate バリデーターなど) に存在する場合、LocalValidatorFactoryBean は、@Controller メソッド引数の @Valid および @Validated で使用するグローバルバリデーターとして登録されます。

Java 構成では、次の例に示すように、グローバル Validator インスタンスをカスタマイズできます。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public Validator getValidator() {
		// ...
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun getValidator(): Validator {
		// ...
	}

}

次の例に示すように、Validator 実装をローカルに登録することもできます。

  • Java

  • Kotlin

@Controller
public class MyController {

	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.addValidators(new FooValidator());
	}

}
@Controller
class MyController {

	@InitBinder
	protected fun initBinder(binder: WebDataBinder) {
		binder.addValidators(FooValidator())
	}
}
LocalValidatorFactoryBean をどこかに挿入する必要がある場合は、Bean を作成し、@Primary でマークして、MVC config で宣言されたものとの競合を回避します。

コンテンツ型リゾルバー

Spring WebFlux が、リクエストから @Controller インスタンスのリクエストされたメディア型を決定する方法を設定できます。デフォルトでは、Accept ヘッダーのみがチェックされますが、クエリパラメーターベースの戦略を有効にすることもできます。

次の例は、リクエストされたコンテンツ型の解決をカスタマイズする方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
		// ...
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureContentTypeResolver(builder: RequestedContentTypeResolverBuilder) {
		// ...
	}
}

HTTP メッセージコーデック

次の例は、リクエストとレスポンスの本文の読み取りおよび書き込み方法をカスタマイズする方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
		configurer.defaultCodecs().maxInMemorySize(512 * 1024);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
		configurer.defaultCodecs().maxInMemorySize(512 * 1024)
	}
}

ServerCodecConfigurer は、デフォルトのリーダーとライターのセットを提供します。これを使用して、リーダーとライターを追加したり、デフォルトのものをカスタマイズしたり、デフォルトのものを完全に置き換えたりできます。

Jackson JSON および XML の場合、Jackson2ObjectMapperBuilder (Javadoc) の使用を検討してください。Jackson2ObjectMapperBuilder (Javadoc) は、Jackson のデフォルトプロパティを次のようにカスタマイズします。

また、次の既知のモジュールがクラスパスで検出された場合、自動的に登録します。

リゾルバーを表示

次の例は、ビューリゾルバーを構成する方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		// ...
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		// ...
	}
}

ViewResolverRegistry には、Spring Framework が統合するビューテクノロジーへのショートカットがあります。次の例では、FreeMarker を使用しています(これには、基になる FreeMarker ビューテクノロジの構成も必要です)

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.freeMarker();
	}

	// Configure Freemarker...

	@Bean
	public FreeMarkerConfigurer freeMarkerConfigurer() {
		FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
		configurer.setTemplateLoaderPath("classpath:/templates");
		return configurer;
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.freeMarker()
	}

	// Configure Freemarker...

	@Bean
	fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
		setTemplateLoaderPath("classpath:/templates")
	}
}

次の例に示すように、ViewResolver 実装をプラグインすることもできます。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		ViewResolver resolver = ... ;
		registry.viewResolver(resolver);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		val resolver: ViewResolver = ...
		registry.viewResolver(resolver
	}
}

コンテンツネゴシエーションをサポートし、ビューリゾルバー (HTML 以外) を介して他の形式をレンダリングするには、spring-web から利用可能なコーデックのいずれかを受け入れる HttpMessageWriterView 実装に基づいて、1 つまたは複数の既定のビューを構成できます。次の例は、その方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {


	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.freeMarker();

		Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
		registry.defaultViews(new HttpMessageWriterView(encoder));
	}

	// ...
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {


	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.freeMarker()

		val encoder = Jackson2JsonEncoder()
		registry.defaultViews(HttpMessageWriterView(encoder))
	}

	// ...
}

Spring WebFlux と統合されているビューテクノロジーの詳細については、ビューテクノロジーを参照してください。

静的リソース

このオプションは、Resource (Javadoc) ベースの場所のリストから静的リソースを提供する便利な方法を提供します。

次の例では、/resources で始まるリクエストを指定すると、相対パスを使用して、クラスパス上の /static に関連する静的リソースを見つけて提供します。ブラウザーのキャッシュを最大限に活用し、ブラウザーによる HTTP リクエストを削減するために、リソースには 1 年間の有効期限が設定されています。Last-Modified ヘッダーも評価され、存在する場合は 304 ステータスコードが返されます。次のリストは、例を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public", "classpath:/static/")
				.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public", "classpath:/static/")
				.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
	}
}

リソースハンドラーは、ResourceResolver (Javadoc) 実装と ResourceTransformer (Javadoc) 実装のチェーンもサポートしています。これらを使用して、最適化されたリソースを操作するためのツールチェーンを作成できます。

コンテンツ、固定アプリケーションバージョン、その他の情報から計算された MD5 ハッシュに基づいて、バージョン管理されたリソース URL に VersionResourceResolver を使用できます。ContentVersionStrategy (MD5 ハッシュ)は、いくつかの注目すべき例外(モジュールローダーで使用される JavaScript リソースなど)がある場合に適しています。

次の例は、Java 構成で VersionResourceResolver を使用する方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public/")
				.resourceChain(true)
				.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
	}

}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
		registry.addResourceHandler("/resources/**")
				.addResourceLocations("/public/")
				.resourceChain(true)
				.addResolver(VersionResourceResolver().addContentVersionStrategy("/**"))
	}

}

ResourceUrlProvider を使用して URL を書き換え、リゾルバーとトランスフォーマーの完全なチェーンを適用できます(たとえば、バージョンを挿入するため)。WebFlux 構成は、ResourceUrlProvider を提供するため、他に注入することができます。

Spring MVC とは異なり、現時点では、WebFlux には静的リソース URL を透過的に書き換える方法がありません。これは、リゾルバーとトランスフォーマーの非ブロックチェーン を利用できるビューテクノロジーがないためです。ローカルリソースのみを提供する場合の回避策は、ResourceUrlProvider を直接 (たとえば、カスタム要素を介して) 使用してブロックすることです。

EncodedResourceResolver (たとえば、Gzip、Brotli エンコード)と VersionedResourceResolver の両方を使用する場合、エンコードされていないファイルに基づいてコンテンツベースのバージョンが常に確実に計算されるように、この順序で登録する必要があります。

WebJars (英語) の場合、/webjars/jquery/1.2.0/jquery.min.js のようなバージョン管理された URL が推奨され、最も効率的な使用方法です。関連するリソースの場所は Spring Boot を使用してすぐに構成でき (または ResourceHandlerRegistry を介して手動で構成できます)、org.webjars:webjars-locator-core 依存関係を追加する必要はありません。

/webjars/jquery/jquery.min.js のようなバージョンのない URL は、org.webjars:webjars-locator-core ライブラリがクラスパスに存在する場合に自動的に登録される WebJarsResourceResolver を介してサポートされますが、アプリケーションの起動を遅くする可能性のあるクラスパススキャンが犠牲になります。リゾルバーは、jar のバージョンを含むように URL を書き換えることができます。また、バージョンのない受信 URL (たとえば、/webjars/jquery/jquery.min.js から /webjars/jquery/1.2.0/jquery.min.js へ) と照合することもできます。

ResourceHandlerRegistry に基づく Java 構成は、きめ細かい制御のための追加オプションを提供します。最終変更された動作と最適化されたリソース解決。

パスマッチング

パスマッチングに関連するオプションをカスタマイズできます。個々のオプションの詳細については、PathMatchConfigurer javadoc を参照してください。次の例は、PathMatchConfigurer の使用方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		configurer.addPathPrefix(
				"/api", HandlerTypePredicate.forAnnotation(RestController.class));
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	@Override
	fun configurePathMatch(configurer: PathMatchConfigurer) {
		configurer.addPathPrefix(
				"/api", HandlerTypePredicate.forAnnotation(RestController::class.java))
	}
}

Spring WebFlux は、デコードされたパスセグメント値にアクセスするために、RequestPath と呼ばれるリクエストパスの解析済み表現に依存しています。セミコロンの内容は削除されています (つまり、パスまたはマトリックス変数)。つまり、Spring MVC とは異なり、リクエストパスをデコードするかどうか、パスマッチングの目的でセミコロンコンテンツを削除するかどうかを指定する必要はありません。

Spring WebFlux も、Spring MVC とは異なり、サフィックスパターンマッチングをサポートしていません。Spring MVC では、それに依存しないようにすることをお勧めします

実行のブロック

WebFlux Java 構成を使用すると、WebFlux でのブロック実行をカスタマイズできます。

次のように VirtualThreadTaskExecutor (Javadoc) などの AsyncTaskExecutor を指定すると、ブロッキングコントローラーメソッドを別のスレッドで呼び出すことができます。

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public void configureBlockingExecution(BlockingExecutionConfigurer configurer) {
		AsyncTaskExecutor executor = ...
		configurer.setExecutor(executor);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	@Override
	fun configureBlockingExecution(configurer: BlockingExecutionConfigurer) {
		val executor = ...
		configurer.setExecutor(executor)
	}
}

デフォルトでは、戻り値の型が構成された ReactiveAdapterRegistry によって認識されないコントローラーメソッドはブロッキングとみなされますが、BlockingExecutionConfigurer を介してカスタムコントローラーメソッド述語を設定できます。

WebSocketService

WebFlux Java 構成は、WebSocket ハンドラーの呼び出しのサポートを提供する WebSocketHandlerAdapter Bean を宣言します。つまり、WebSocket ハンドシェイクリクエストを処理するために必要なことは、WebSocketHandler を SimpleUrlHandlerMapping を介して URL にマップすることだけです。

場合によっては、WebSocket サーバーのプロパティを構成できる WebSocketService サービスを提供して WebSocketHandlerAdapter Bean を作成する必要があります。例:

  • Java

  • Kotlin

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

	@Override
	public WebSocketService getWebSocketService() {
		TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
		strategy.setMaxSessionIdleTimeout(0L);
		return new HandshakeWebSocketService(strategy);
	}
}
@Configuration
@EnableWebFlux
class WebConfig : WebFluxConfigurer {

	@Override
	fun webSocketService(): WebSocketService {
		val strategy = TomcatRequestUpgradeStrategy().apply {
			setMaxSessionIdleTimeout(0L)
		}
		return HandshakeWebSocketService(strategy)
	}
}

拡張構成モード

@EnableWebFlux は DelegatingWebFluxConfiguration をインポートします:

  • WebFlux アプリケーションにデフォルトの Spring 構成を提供します

  • WebFluxConfigurer 実装を検出して委譲し、その構成をカスタマイズします。

拡張モードの場合、次の例に示すように、WebFluxConfigurer を実装する代わりに、@EnableWebFlux を削除して DelegatingWebFluxConfiguration から直接拡張できます。

  • Java

  • Kotlin

@Configuration
public class WebConfig extends DelegatingWebFluxConfiguration {

	// ...
}
@Configuration
class WebConfig : DelegatingWebFluxConfiguration {

	// ...
}

既存のメソッドを WebConfig に保持できますが、ベースクラスからの Bean 宣言をオーバーライドしても、クラスパスに他の WebMvcConfigurer 実装をいくつでも持つことができます。