サーブレット Web アプリケーション
サーブレットベースの Web アプリケーションを構築する場合は、Spring MVC または Jersey 用の Spring Boot の自動構成を利用できます。
「Spring Web MVC フレームワーク」
Spring Web MVC フレームワーク ( "Spring MVC" と呼ばれることが多い) は、リッチな「モデル、ビュー、コントローラー」Web フレームワークです。Spring MVC を使用すると、受信 HTTP リクエストを処理するための特別な @Controller
または @RestController
Bean を作成できます。コントローラーのメソッドは、@RequestMapping
アノテーションを使用して HTTP にマップされます。
次のコードは、JSON データを提供する典型的な @RestController
を示しています。
Java
Kotlin
import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class MyRestController {
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
@GetMapping("/{userId}")
public User getUser(@PathVariable Long userId) {
return this.userRepository.findById(userId).get();
}
@GetMapping("/{userId}/customers")
public List<Customer> getUserCustomers(@PathVariable Long userId) {
return this.userRepository.findById(userId).map(this.customerRepository::findByUser).get();
}
@DeleteMapping("/{userId}")
public void deleteUser(@PathVariable Long userId) {
this.userRepository.deleteById(userId);
}
}
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/users")
class MyRestController(private val userRepository: UserRepository, private val customerRepository: CustomerRepository) {
@GetMapping("/{userId}")
fun getUser(@PathVariable userId: Long): User {
return userRepository.findById(userId).get()
}
@GetMapping("/{userId}/customers")
fun getUserCustomers(@PathVariable userId: Long): List<Customer> {
return userRepository.findById(userId).map(customerRepository::findByUser).get()
}
@DeleteMapping("/{userId}")
fun deleteUser(@PathVariable userId: Long) {
userRepository.deleteById(userId)
}
}
次の例に示すように、関数型バリアントである "WebMvc.fn" は、ルーティング構成をリクエストの実際の処理から分離します。
Java
Kotlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;
import static org.springframework.web.servlet.function.RequestPredicates.accept;
import static org.springframework.web.servlet.function.RouterFunctions.route;
@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {
private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);
@Bean
public RouterFunction<ServerResponse> routerFunction(MyUserHandler userHandler) {
return route()
.GET("/{user}", ACCEPT_JSON, userHandler::getUser)
.GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
.DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
.build();
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.web.servlet.function.RequestPredicates.accept
import org.springframework.web.servlet.function.RouterFunction
import org.springframework.web.servlet.function.RouterFunctions
import org.springframework.web.servlet.function.ServerResponse
@Configuration(proxyBeanMethods = false)
class MyRoutingConfiguration {
@Bean
fun routerFunction(userHandler: MyUserHandler): RouterFunction<ServerResponse> {
return RouterFunctions.route()
.GET("/{user}", ACCEPT_JSON, userHandler::getUser)
.GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
.DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
.build()
}
companion object {
private val ACCEPT_JSON = accept(MediaType.APPLICATION_JSON)
}
}
Java
Kotlin
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;
@Component
public class MyUserHandler {
public ServerResponse getUser(ServerRequest request) {
...
}
public ServerResponse getUserCustomers(ServerRequest request) {
...
}
public ServerResponse deleteUser(ServerRequest request) {
...
}
}
import org.springframework.stereotype.Component
import org.springframework.web.servlet.function.ServerRequest
import org.springframework.web.servlet.function.ServerResponse
@Component
class MyUserHandler {
fun getUser(request: ServerRequest?): ServerResponse {
...
}
fun getUserCustomers(request: ServerRequest?): ServerResponse {
...
}
fun deleteUser(request: ServerRequest?): ServerResponse {
...
}
}
Spring MVC はコア Spring Framework の一部であり、詳細情報はリファレンスドキュメントで入手できます。spring.io/guides で入手可能な Spring MVC をカバーするガイドもいくつかあります。
RouterFunction Bean をいくつでも定義して、ルーターの定義をモジュール化できます。優先順位を適用する必要がある場合は、Bean をオーダーできます。 |
Spring MVC 自動構成
Spring Boot は、ほとんどのアプリケーションで適切に動作する Spring MVC の自動構成を提供します。これは @EnableWebMvc
の必要性を置き換えるものであり、2 つを一緒に使用することはできません。Spring MVC のデフォルトに加えて、自動構成では次の機能が提供されます。
ContentNegotiatingViewResolver
およびBeanNameViewResolver
Bean の包含。WebJars のサポートを含む静的リソースの提供のサポート(このドキュメントで後述)。
Converter
、GenericConverter
、Formatter
Bean の自動登録。HttpMessageConverters
のサポート(このドキュメントで後述)。MessageCodesResolver
の自動登録(このドキュメントで後述)。静的
index.html
サポート。ConfigurableWebBindingInitializer
Bean の自動使用(このドキュメントで後述)。
これらの Spring Boot MVC のカスタマイズを保持し、さらに MVC のカスタマイズ(インターセプター、フォーマッター、View Controller、およびその他の機能)を作成する場合は、@EnableWebMvc
なしで型 WebMvcConfigurer
の独自の @Configuration
クラスを追加できます。
RequestMappingHandlerMapping
、RequestMappingHandlerAdapter
、または ExceptionHandlerExceptionResolver
のカスタムインスタンスを提供し、Spring Boot MVC カスタマイズを保持したい場合は、WebMvcRegistrations
型の Bean を宣言し、それを使用してこれらのコンポーネントのカスタムインスタンスを提供できます。カスタムインスタンスは、Spring MVC によるさらなる初期化と構成の対象になります。後続の処理に参加し、必要に応じてオーバーライドするには、WebMvcConfigurer
を使用する必要があります。
自動構成を使用せず、Spring MVC を完全に制御したい場合は、@EnableWebMvc
でアノテーションを付けた独自の @Configuration
を追加します。または、@EnableWebMvc
API ドキュメントの説明に従って、@Configuration
でアノテーションを付けた独自の DelegatingWebMvcConfiguration
を追加します。
Spring MVC 変換サービス
Spring MVC は、application.properties
または application.yaml
ファイルから値を変換するために使用されるものとは異なる ConversionService
を使用します。これは、Period
、Duration
、DataSize
コンバーターが使用できず、@DurationUnit
および @DataSizeUnit
アノテーションが無視されることを意味します。
Spring MVC が使用する ConversionService
をカスタマイズする場合は、WebMvcConfigurer
Bean に addFormatters
メソッドを提供できます。このメソッドから、好きなコンバーターを登録したり、ApplicationConversionService
で利用可能な静的メソッドに委譲したりできます。
変換は、spring.mvc.format.*
構成プロパティを使用してカスタマイズすることもできます。構成されていない場合は、次のデフォルトが使用されます。
プロパティ | DateTimeFormatter | フォーマット |
---|---|---|
|
|
|
|
| java.time の |
|
| java.time の |
HttpMessageConverters
Spring MVC は、HttpMessageConverter
インターフェースを使用して HTTP リクエストとレスポンスを変換します。適切なデフォルトは、すぐに含まれています。例: オブジェクトは、JSON (Jackson ライブラリを使用) または XML (使用可能な場合は Jackson XML 拡張を使用するか、Jackson XML 拡張が使用できない場合は JAXB を使用) に自動的に変換できます。デフォルトでは、文字列は UTF-8
でエンコードされます。
コンテキストに存在する HttpMessageConverter
Bean は、コンバーターのリストに追加されます。同じ方法でデフォルトのコンバーターをオーバーライドすることもできます。
コンバーターを追加またはカスタマイズする必要がある場合は、次のように、Spring Boot の HttpMessageConverters
クラスを使用できます。
Java
Kotlin
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
@Configuration(proxyBeanMethods = false)
public class MyHttpMessageConvertersConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = new AdditionalHttpMessageConverter();
HttpMessageConverter<?> another = new AnotherHttpMessageConverter();
return new HttpMessageConverters(additional, another);
}
}
import org.springframework.boot.autoconfigure.http.HttpMessageConverters
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.HttpMessageConverter
@Configuration(proxyBeanMethods = false)
class MyHttpMessageConvertersConfiguration {
@Bean
fun customConverters(): HttpMessageConverters {
val additional: HttpMessageConverter<*> = AdditionalHttpMessageConverter()
val another: HttpMessageConverter<*> = AnotherHttpMessageConverter()
return HttpMessageConverters(additional, another)
}
}
さらに制御するには、HttpMessageConverters
をサブクラス化し、その postProcessConverters
および / または postProcessPartConverters
メソッドをオーバーライドすることもできます。これは、Spring MVC がデフォルトで構成するコンバーターの一部を並べ替えたり削除したりする場合に役立ちます。
MessageCodesResolver
Spring MVC には、バインディングエラーからエラーメッセージをレンダリングするためのエラーコードを生成する戦略があります: MessageCodesResolver
。spring.mvc.message-codes-resolver-format
プロパティ PREFIX_ERROR_CODE
または POSTFIX_ERROR_CODE
を設定すると、Spring Boot によってエラーコードが作成されます ( DefaultMessageCodesResolver.Format (Javadoc)
の列挙を参照)。
静的コンテンツ
デフォルトでは、Spring Boot は、クラスパス内の /static
(または /public
または /resources
または /META-INF/resources
) というディレクトリから、または ServletContext
のルートから静的コンテンツを提供します。Spring MVC の ResourceHttpRequestHandler
を使用しているため、独自の WebMvcConfigurer
を追加して addResourceHandlers
メソッドをオーバーライドすることで、その動作を変更できます。
スタンドアロン Web アプリケーションでは、コンテナーのデフォルトサーブレットは有効になっていません。server.servlet.register-default-servlet
プロパティを使用して有効にすることができます。
デフォルトのサーブレットはフォールバックとして機能し、Spring が処理しないと決定した場合に ServletContext
のルートからコンテンツを提供します。Spring は常に DispatcherServlet
を介してリクエストを処理できるため、ほとんどの場合、これは発生しません (デフォルトの MVC 構成を変更しない限り)。
デフォルトでは、リソースは /**
にマップされますが、spring.mvc.static-path-pattern
プロパティでそれを調整できます。たとえば、すべてのリソースを /resources/**
に再配置するには、次のようにします。
プロパティ
YAML
spring.mvc.static-path-pattern=/resources/**
spring:
mvc:
static-path-pattern: "/resources/**"
spring.web.resources.static-locations
プロパティを使用して静的リソースの場所をカスタマイズすることもできます(デフォルト値をディレクトリの場所のリストに置き換えます)。ルートサーブレットコンテキストパス "/"
も、場所として自動的に追加されます。
前述の「標準」の静的リソースの場所に加えて、Webjars コンテンツ (英語) には特別なケースが作成されます。デフォルトでは、パスが /webjars/**
のリソースは、Webjars 形式でパッケージ化されている場合、jar ファイルから提供されます。パスは spring.mvc.webjars-path-pattern
プロパティでカスタマイズできます。
アプリケーションが jar としてパッケージ化されている場合は、src/main/webapp ディレクトリを使用しないでください。このディレクトリは一般的な標準ですが、war パッケージでのみ機能し、jar を生成する場合、ほとんどのビルドツールでは暗黙のうちに無視されます。 |
Spring Boot は、Spring MVC が提供する高度なリソース処理機能もサポートし、静的リソースのキャッシュ無効化や Webjar のバージョンに依存しない URL の使用などのユースケースを可能にします。
Webjar のバージョンに依存しない URL を使用するには、webjars-locator-core
依存関係を追加します。次に、Webjar を宣言します。jQuery を例にとると、"/webjars/jquery/jquery.min.js"
を追加すると "/webjars/jquery/x.y.z/jquery.min.js"
になります。ここで、x.y.z
は Webjar のバージョンです。
JBoss を使用する場合、webjars-locator-core ではなく webjars-locator-jboss-vfs 依存関係を宣言する必要があります。それ以外の場合、すべての Webjar は 404 として解決されます。 |
キャッシュ無効化を使用するには、次の構成ですべての静的リソースのキャッシュ無効化ソリューションを構成し、URL に <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
などのコンテンツハッシュを効果的に追加します。
プロパティ
YAML
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
spring:
web:
resources:
chain:
strategy:
content:
enabled: true
paths: "/**"
Thymeleaf および FreeMarker 用に自動構成された ResourceUrlEncodingFilter により、リソースへのリンクは実行時にテンプレート内で書き換えられます。JSP を使用する場合は、このフィルターを手動で宣言する必要があります。他のテンプレートエンジンは現在自動的にはサポートされていませんが、カスタムテンプレートマクロ / ヘルパーと ResourceUrlProvider (Javadoc) の使用によりサポートできます。 |
JavaScript モジュールローダーなどを使用してリソースを動的にロードする場合、ファイルの名前を変更することはできません。そのため、他の戦略もサポートされており、組み合わせることができます。"fixed" 戦略では、次の例に示すように、ファイル名を変更せずに URL に静的バージョン文字列を追加します。
プロパティ
YAML
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
spring.web.resources.chain.strategy.fixed.enabled=true
spring.web.resources.chain.strategy.fixed.paths=/js/lib/
spring.web.resources.chain.strategy.fixed.version=v12
spring:
web:
resources:
chain:
strategy:
content:
enabled: true
paths: "/**"
fixed:
enabled: true
paths: "/js/lib/"
version: "v12"
この構成では、"/js/lib/"
にある JavaScript モジュールは固定バージョン管理戦略("/v12/js/lib/mymodule.js"
)を使用しますが、他のリソースはコンテンツコンテンツ(<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
)を引き続き使用します。
サポートされているその他のオプションについては、WebProperties.Resources (Javadoc)
を参照してください。
この機能は、専用のブログ投稿 (英語) および Spring Framework のリファレンスドキュメントで詳細に説明されています。 |
ウェルカムページ
Spring Boot は、静的なウェルカムページとテンプレート化されたウェルカムページの両方をサポートしています。最初に、構成された静的コンテンツの場所で index.html
ファイルを探します。見つからない場合は、index
テンプレートを探します。どちらかが見つかった場合、アプリケーションのウェルカムページとして自動的に使用されます。
これは、アプリケーションによって定義された実際のインデックスルートのフォールバックとしてのみ機能します。順序は HandlerMapping
Bean の順序によって定義され、デフォルトでは次のようになります。
|
|
|
|
| ようこそページのサポート |
カスタムファビコン
他の静的リソースと同様に、Spring Boot は構成された静的コンテンツの場所で favicon.ico
をチェックします。そのようなファイルが存在する場合、アプリケーションのファビコンとして自動的に使用されます。
パスマッチングとコンテンツネゴシエーション
Spring MVC は、リクエストパスを調べて、アプリケーションで定義されたマッピング (たとえば、コントローラーメソッドの @GetMapping
アノテーション) と照合することにより、受信 HTTP リクエストをハンドラーにマッピングできます。
Spring Boot は、デフォルトでサフィックスパターンマッチングを無効にすることを選択します。これは、"GET /projects/spring-boot.json"
のようなリクエストが @GetMapping("/projects/spring-boot")
マッピングにマッチングされないことを意味します。これは、Spring MVC アプリケーションのベストプラクティスと見なされています。この機能は、これまで、適切な "Accept" リクエストヘッダーを送信しなかった HTTP クライアントで主に役立ちました。正しいコンテンツ型をクライアントに送信する必要がありました。今日では、コンテントネゴシエーションの信頼性ははるかに高くなっています。
適切な "Accept" リクエストヘッダーを一貫して送信しない HTTP クライアントを処理する方法は他にもあります。サフィックスマッチングを使用する代わりに、クエリパラメーターを使用して、"GET /projects/spring-boot?format=json"
などのリクエストが @GetMapping("/projects/spring-boot")
にマップされるようにすることができます。
プロパティ
YAML
spring.mvc.contentnegotiation.favor-parameter=true
spring:
mvc:
contentnegotiation:
favor-parameter: true
または、別のパラメーター名を使用する場合:
プロパティ
YAML
spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.parameter-name=myparam
spring:
mvc:
contentnegotiation:
favor-parameter: true
parameter-name: "myparam"
ほとんどの標準メディア型はすぐにサポートされますが、新しいメディア型を定義することもできます。
プロパティ
YAML
spring.mvc.contentnegotiation.media-types.markdown=text/markdown
spring:
mvc:
contentnegotiation:
media-types:
markdown: "text/markdown"
Spring Framework 5.3 の時点で、Spring MVC は、コントローラーへのリクエストパスを照合するための 2 つの戦略をサポートしています。デフォルトでは、Spring Boot は PathPatternParser
戦略を使用します。PathPatternParser
は最適化された実装 (英語) ですが、AntPathMatcher
戦略と比較していくつかの制限があります。PathPatternParser
は、一部のパスパターンバリアントの使用を制限します。また、パスプレフィックス (spring.mvc.servlet.path
) を使用して DispatcherServlet
を構成することとも互換性がありません。
次の例に示すように、戦略は spring.mvc.pathmatch.matching-strategy
構成プロパティを使用して構成できます。
プロパティ
YAML
spring.mvc.pathmatch.matching-strategy=ant-path-matcher
spring:
mvc:
pathmatch:
matching-strategy: "ant-path-matcher"
リクエストのハンドラーが見つからない場合、Spring MVC は NoHandlerFoundException
をスローします。デフォルトでは、静的コンテンツの提供は /**
にマップされるため、すべてのリクエストにハンドラーが提供されることに注意してください。静的コンテンツが利用できない場合、ResourceHttpRequestHandler
は NoResourceFoundException
をスローします。NoHandlerFoundException
をスローするには、spring.mvc.static-path-pattern
を /resources/**
などのより具体的な値に設定するか、spring.web.resources.add-mappings
を false
に設定して静的コンテンツの提供を完全に無効にします。
ConfigurableWebBindingInitializer
Spring MVC は WebBindingInitializer
を使用して、特定のリクエストに対して WebDataBinder
を初期化します。独自の ConfigurableWebBindingInitializer
@Bean
を作成すると、Spring Boot はそれを使用するように Spring MVC を自動的に構成します。
テンプレートエンジン
REST Web サービスだけでなく、Spring MVC を使用して動的 HTML コンテンツを提供することもできます。Spring MVC は、Thymeleaf、FreeMarker、JSP など、さまざまなテンプレートテクノロジをサポートしています。また、他の多くのテンプレートエンジンには、独自の Spring MVC 統合が含まれています。
Spring Boot には、次のテンプレートエンジンの自動構成サポートが含まれています。
可能であれば、JSP を避ける必要があります。組み込みサーブレットコンテナーで使用する場合、いくつかの既知の制限があります。 |
これらのテンプレートエンジンのいずれかを既定の構成で使用すると、src/main/resources/templates
からテンプレートが自動的に選択されます。
アプリケーションの実行メソッドに応じて、IDE はクラスパスの順序を変える場合があります。IDE でメインメソッドからアプリケーションを実行すると、Maven または Gradle を使用して、またはパッケージ化された jar からアプリケーションを実行する場合とは異なる順序になります。これにより、Spring Boot が予期されたテンプレートを見つけられない可能性があります。この問題が発生した場合は、IDE でクラスパスを並べ替えて、モジュールのクラスとリソースを最初に配置できます。 |
エラー処理
デフォルトでは、Spring Boot はすべてのエラーを適切な方法で処理する /error
マッピングを提供し、サーブレットコンテナーに「グローバル」エラーページとして登録されます。マシンクライアントの場合、エラー、HTTP ステータス、例外メッセージの詳細を含む JSON レスポンスを生成します。ブラウザークライアントの場合、同じデータを HTML 形式でレンダリングする「ホワイトラベル」エラービューがあります(カスタマイズするには、error
に解決される View
を追加します)。
デフォルトのエラー処理動作をカスタマイズする場合に設定できる server.error
プロパティがいくつかあります。付録のサーバープロパティセクションを参照してください。
デフォルトの動作を完全に置き換えるには、ErrorController
を実装してその型の Bean 定義を登録するか、型 ErrorAttributes
の Bean を追加して既存のメカニズムを使用しますが、内容を置き換えます。
BasicErrorController は、カスタム ErrorController の基本クラスとして使用できます。これは、新しいコンテンツ型のハンドラーを追加する場合に特に便利です(デフォルトでは、text/html を具体的に処理し、他のすべてにフォールバックを提供します)。これを行うには、BasicErrorController を継承し、produces 属性を持つ @RequestMapping を使用して public メソッドを追加し、新しい型の Bean を作成します。 |
Spring Framework 6.0 の時点で、RFC 9457 問題の詳細がサポートされています。Spring MVC は、次のような application/problem+json
メディア型でカスタムエラーメッセージを生成できます。
{
"type": "https://example.org/problems/unknown-project",
"title": "Unknown project",
"status": 404,
"detail": "No project found for id 'spring-unknown'",
"instance": "/projects/spring-unknown"
}
このサポートは、spring.mvc.problemdetails.enabled
を true
に設定することで有効にできます。
次の例に示すように、@ControllerAdvice
アノテーションが付けられたクラスを定義して、特定のコントローラーまたは例外型、あるいはその両方を返すように JSON ドキュメントをカスタマイズすることもできます。
Java
Kotlin
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice(basePackageClasses = SomeController.class)
public class MyControllerAdvice extends ResponseEntityExceptionHandler {
@ResponseBody
@ExceptionHandler(MyException.class)
public ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new MyErrorBody(status.value(), ex.getMessage()), status);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer code = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
HttpStatus status = HttpStatus.resolve(code);
return (status != null) ? status : HttpStatus.INTERNAL_SERVER_ERROR;
}
}
import jakarta.servlet.RequestDispatcher
import jakarta.servlet.http.HttpServletRequest
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
@ControllerAdvice(basePackageClasses = [SomeController::class])
class MyControllerAdvice : ResponseEntityExceptionHandler() {
@ResponseBody
@ExceptionHandler(MyException::class)
fun handleControllerException(request: HttpServletRequest, ex: Throwable): ResponseEntity<*> {
val status = getStatus(request)
return ResponseEntity(MyErrorBody(status.value(), ex.message), status)
}
private fun getStatus(request: HttpServletRequest): HttpStatus {
val code = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE) as Int
val status = HttpStatus.resolve(code)
return status ?: HttpStatus.INTERNAL_SERVER_ERROR
}
}
上記の例では、MyException
が SomeController
と同じパッケージで定義されたコントローラーによってスローされた場合、ErrorAttributes
表現の代わりに MyErrorBody
POJO の JSON 表現が使用されます。
場合によっては、コントローラーレベルで処理されたエラーが Web 観察やメトリクスインフラストラクチャによって記録されないことがあります。アプリケーションは、処理された例外を観測コンテキストに設定することにより、そのような例外が観測とともに確実に記録されるようにすることができます。
カスタムエラーページ
特定のステータスコードのカスタム HTML エラーページを表示する場合は、/error
ディレクトリにファイルを追加できます。エラーページは、静的 HTML(つまり、任意の静的リソースディレクトリに追加される)にすることも、テンプレートを使用して作成することもできます。ファイルの名前は、正確なステータスコードまたはシリーズマスクである必要があります。
例: 404
を静的 HTML ファイルにマップするには、ディレクトリ構造は次のようになります。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
FreeMarker テンプレートを使用してすべての 5xx
エラーをマップするには、ディレクトリ構造は次のようになります。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftlh
+- <other templates>
より複雑なマッピングの場合、次の例に示すように、ErrorViewResolver
インターフェースを実装する Bean を追加することもできます。
Java
Kotlin
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.ModelAndView;
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
if (status == HttpStatus.INSUFFICIENT_STORAGE) {
// We could add custom model values here
new ModelAndView("myview");
}
return null;
}
}
import jakarta.servlet.http.HttpServletRequest
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver
import org.springframework.http.HttpStatus
import org.springframework.web.servlet.ModelAndView
class MyErrorViewResolver : ErrorViewResolver {
override fun resolveErrorView(request: HttpServletRequest, status: HttpStatus,
model: Map<String, Any>): ModelAndView? {
// Use the request or status to optionally return a ModelAndView
if (status == HttpStatus.INSUFFICIENT_STORAGE) {
// We could add custom model values here
return ModelAndView("myview")
}
return null
}
}
@ExceptionHandler
メソッドや @ControllerAdvice
などの通常の Spring MVC 機能も使用できます。その後、ErrorController
は未処理の例外を取得します。
Spring MVC 以外のエラーページのマッピング
Spring MVC を使用しないアプリケーションの場合、ErrorPageRegistrar
インターフェースを使用して ErrorPages
を直接登録できます。この抽象化は、基盤となる埋め込みサーブレットコンテナーと直接連携し、Spring MVC DispatcherServlet
がなくても機能します。
Java
Kotlin
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
@Configuration(proxyBeanMethods = false)
public class MyErrorPagesConfiguration {
@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return this::registerErrorPages;
}
private void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
}
}
import org.springframework.boot.web.server.ErrorPage
import org.springframework.boot.web.server.ErrorPageRegistrar
import org.springframework.boot.web.server.ErrorPageRegistry
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpStatus
@Configuration(proxyBeanMethods = false)
class MyErrorPagesConfiguration {
@Bean
fun errorPageRegistrar(): ErrorPageRegistrar {
return ErrorPageRegistrar { registry: ErrorPageRegistry -> registerErrorPages(registry) }
}
private fun registerErrorPages(registry: ErrorPageRegistry) {
registry.addErrorPages(ErrorPage(HttpStatus.BAD_REQUEST, "/400"))
}
}
Filter によって処理されるパスで ErrorPage を登録する場合(Jersey や Wicket などの一部の非 SpringWeb フレームワークで一般的)、次に示すように、Filter を ERROR ディスパッチャーとして明示的に登録する必要があります。次の例: |
Java
Kotlin
import java.util.EnumSet;
import jakarta.servlet.DispatcherType;
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> myFilter() {
FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(new MyFilter());
// ...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
}
import jakarta.servlet.DispatcherType
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.util.EnumSet
@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {
@Bean
fun myFilter(): FilterRegistrationBean<MyFilter> {
val registration = FilterRegistrationBean(MyFilter())
// ...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType::class.java))
return registration
}
}
デフォルトの FilterRegistrationBean
には ERROR
ディスパッチャー型が含まれていないことに注意してください。
WAR デプロイでのエラー処理
サーブレットコンテナーにデプロイされると、Spring Boot はエラーページフィルターを使用して、エラーステータスのあるリクエストを適切なエラーページに転送します。サーブレット仕様ではエラーページを登録するための API が提供されていないため、これが必要です。war ファイルをデプロイするコンテナーとアプリケーションが使用するテクノロジーによっては、追加の構成が必要になる場合があります。
エラーページフィルターは、レスポンスがまだコミットされていない場合にのみ、リクエストを正しいエラーページに転送できます。デフォルトでは、WebSphere アプリケーションサーバー 8.0 以降は、サーブレットのサービスメソッドが正常に完了すると、レスポンスをコミットします。com.ibm.ws.webcontainer.invokeFlushAfterService
を false
に設定して、この動作を無効にする必要があります。
CORS サポート
クロスオリジンリソース共有 [Mozilla] (CORS)は、ほとんどのブラウザー (英語) で実装されている W3C 仕様 (英語) であり、IFRAME や JSONP などの安全性の低いアプローチを使用する代わりに、どのようなクロスドメインリクエストを認可するかを柔軟に指定できます。
バージョン 4.2 以降、Spring MVC は CORS をサポートしています。Spring Boot アプリケーションで @CrossOrigin (Javadoc)
アノテーションを使用してコントローラーメソッドの CORS 構成を使用する場合、特別な構成は必要ありません。次の例に示すように、カスタマイズされた addCorsMappings(CorsRegistry)
メソッドを使用して WebMvcConfigurer
Bean を登録することで、グローバル CORS 設定を定義できます。
Java
Kotlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration(proxyBeanMethods = false)
public class MyCorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration(proxyBeanMethods = false)
class MyCorsConfiguration {
@Bean
fun corsConfigurer(): WebMvcConfigurer {
return object : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/api/**")
}
}
}
}
JAX-RS および Jersey
REST エンドポイントに JAX-RS プログラミングモデルを使用する場合は、Spring MVC の代わりに使用可能な実装の 1 つを使用できます。Jersey (英語) と Apache CXF (英語) は、すぐに使用できます。CXF では、アプリケーションコンテキストで Servlet
または Filter
を @Bean
として登録する必要があります。Jersey にはネイティブ Spring サポートがいくつかあるため、スターターとともに Spring Boot での自動構成サポートも提供します。
Jersey を開始するには、spring-boot-starter-jersey
を依存関係として含めてから、次の例に示すように、すべてのエンドポイントを登録する型 ResourceConfig
の @Bean
が 1 つ必要です。
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
@Component
public class MyJerseyConfig extends ResourceConfig {
public MyJerseyConfig() {
register(MyEndpoint.class);
}
}
Jersey の実行可能アーカイブのスキャンのサポートはかなり制限されています。たとえば、完全に実行可能な jar ファイル内、または実行可能な war ファイルを実行しているときに WEB-INF/classes 内にあるパッケージ内のエンドポイントをスキャンすることはできません。この制限を回避するには、packages メソッドを使用せず、前の例に示すように、register メソッドを使用してエンドポイントを個別に登録する必要があります。 |
より高度なカスタマイズのために、ResourceConfigCustomizer
を実装する Bean を任意の数だけ登録することもできます。
登録されたすべてのエンドポイントは、次の例に示すように、HTTP リソースアノテーション(@GET
など)を含む @Components
である必要があります。
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.springframework.stereotype.Component;
@Component
@Path("/hello")
public class MyEndpoint {
@GET
public String message() {
return "Hello";
}
}
Endpoint
は Spring @Component
であるため、そのライフサイクルは Spring によって管理され、@Autowired
アノテーションを使用して依存関係を注入し、@Value
アノテーションを使用して外部構成を注入できます。デフォルトでは、Jersey サーブレットが登録され、/*
にマップされます。@ApplicationPath
を ResourceConfig
に追加することにより、マッピングを変更できます。
デフォルトでは、Jersey は、jerseyServletRegistration
という名前の ServletRegistrationBean
型の @Bean
のサーブレットとして設定されます。デフォルトでは、サーブレットは遅延初期化されますが、spring.jersey.servlet.load-on-startup
を設定することでその動作をカスタマイズできます。同じ名前で独自の Bean を作成することにより、その Bean を無効化またはオーバーライドできます。spring.jersey.type=filter
を設定することにより、サーブレットの代わりにフィルターを使用することもできます(この場合、置換またはオーバーライドする @Bean
は jerseyFilterRegistration
です)。フィルターには @Order
があり、spring.jersey.filter.order
で設定できます。Jersey をフィルターとして使用する場合、Jersey によってインターセプトされないリクエストを処理するサーブレットが存在する必要があります。アプリケーションにそのようなサーブレットが含まれていない場合は、server.servlet.register-default-servlet
を true
に設定して、デフォルトのサーブレットを有効にすることをお勧めします。spring.jersey.init.*
を使用してプロパティのマップを指定することにより、サーブレットとフィルターの両方の登録に init パラメーターを指定できます。
組み込みサーブレットコンテナーのサポート
サーブレットアプリケーションの場合、Spring Boot には組み込みの Tomcat [Apache] (英語) 、Jetty (英語) 、Undertow [GitHub] (英語) サーバーのサポートが含まれています。ほとんどの開発者は、適切なスターターを使用して、完全に構成されたインスタンスを取得します。デフォルトでは、組み込みサーバーはポート 8080
で HTTP リクエストをリッスンします。
サーブレット、フィルター、リスナー
組み込みサーブレットコンテナーを使用する場合、Spring Bean を使用するか、サーブレットコンポーネントをスキャンすることにより、サーブレット、フィルター、すべてのリスナー(HttpSessionListener
など)をサーブレット仕様から登録できます。
サーブレット、フィルター、リスナーを Spring Bean として登録する
Spring Bean である Servlet
、Filter
、サーブレット *Listener
インスタンスはすべて、組み込みコンテナーに登録されます。これは、構成中に application.properties
から値を参照する場合に特に便利です。
デフォルトでは、コンテキストに含まれるサーブレットが 1 つのみの場合、/
にマッピングされます。複数のサーブレット Bean の場合、Bean 名がパスプレフィックスとして使用されます。フィルターは /*
にマップします。
規則ベースのマッピングに十分な柔軟性がない場合は、ServletRegistrationBean
、FilterRegistrationBean
、ServletListenerRegistrationBean
クラスを使用して完全に制御できます。
通常、フィルター Bean は順序付けされていないままにしておくのが安全です。特定の順序が必要な場合は、Filter
に @Order
のアノテーションを付けるか、Ordered
を実装するようにする必要があります。Bean メソッドに @Order
アノテーションを付けて、Filter
の順序を構成することはできません。Filter
クラスを変更して @Order
を追加したり、Ordered
を実装したりできない場合は、Filter
の FilterRegistrationBean
を定義し、setOrder(int)
メソッドを使用して登録 Bean の順序を設定する必要があります。Ordered.HIGHEST_PRECEDENCE
でリクエスト本文を読み取るフィルターを構成することは避けてください。これは、アプリケーションの文字エンコード構成に反する可能性があるためです。サーブレットフィルターがリクエストをラップする場合は、OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER
以下の順序で設定する必要があります。
アプリケーション内のすべての Filter の順序を確認するには、web ロググループ (logging.level.web=debug ) のデバッグレベルのログ記録を有効にします。登録されたフィルターの詳細 (順序や URL パターンなど) が起動時にログに記録されます。 |
Filter Bean はアプリケーションライフサイクルの非常に早い段階で初期化されるため、登録する際には注意してください。他の Bean と対話する Filter を登録する必要がある場合は、代わりに DelegatingFilterProxyRegistrationBean (Javadoc) の使用を検討してください。 |
サーブレットコンテキストの初期化
組み込みサーブレットコンテナーは、jakarta.servlet.ServletContainerInitializer
インターフェースまたは Spring の org.springframework.web.WebApplicationInitializer
インターフェースを直接実行しません。これは、war 内で実行するように設計されたサードパーティライブラリが Spring Boot アプリケーションを破壊するリスクを減らすことを目的とした意図的な設計上の決定です。
Spring Boot アプリケーションでサーブレットコンテキストの初期化を実行する必要がある場合は、org.springframework.boot.web.servlet.ServletContextInitializer
インターフェースを実装する Bean を登録する必要があります。単一の onStartup
メソッドは ServletContext
へのアクセスを提供し、必要に応じて、既存の WebApplicationInitializer
へのアダプターとして簡単に使用できます。
ServletWebServerApplicationContext
内部的には、Spring Boot は組み込みサーブレットコンテナーのサポートに異なる型の ApplicationContext
を使用します。ServletWebServerApplicationContext
は、単一の ServletWebServerFactory
Bean を検索することによってそれ自体をブートストラップする特殊な型の WebApplicationContext
です。通常、TomcatServletWebServerFactory
、JettyServletWebServerFactory
、UndertowServletWebServerFactory
は自動構成されています。
通常、これらの実装クラスを意識する必要はありません。ほとんどのアプリケーションは自動構成され、適切な ApplicationContext および ServletWebServerFactory がユーザーに代わって作成されます。 |
組み込みコンテナーのセットアップでは、ServletContext
は、アプリケーションコンテキストの初期化中に発生するサーバーの起動の一部として設定されます。このため、ApplicationContext
の Bean は、ServletContext
で確実に初期化できません。これを回避する 1 つの方法は、Bean の依存関係として ApplicationContext
を挿入し、必要な場合にのみ ServletContext
にアクセスすることです。もう 1 つの方法は、サーバーの起動後にコールバックを使用することです。これは、次のように ApplicationStartedEvent
をリッスンする ApplicationListener
を使用して実行できます。
import jakarta.servlet.ServletContext;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.web.context.WebApplicationContext;
public class MyDemoBean implements ApplicationListener<ApplicationStartedEvent> {
private ServletContext servletContext;
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
this.servletContext = ((WebApplicationContext) applicationContext).getServletContext();
}
}
埋め込みサーブレットコンテナーのカスタマイズ
一般的なサーブレットコンテナー設定は、Spring Environment
プロパティを使用して構成できます。通常、application.properties
または application.yaml
ファイルでプロパティを定義します。
一般的なサーバー設定は次のとおりです。
ネットワーク設定: 受信 HTTP リクエストのリッスンポート (
server.port
)、バインド先のインターフェースアドレス (server.address
) など。セッション設定: セッションが永続的か(
server.servlet.session.persistent
)、セッションタイムアウト(server.servlet.session.timeout
)、セッションデータの場所(server.servlet.session.store-dir
)、セッション Cookie 構成(server.servlet.session.cookie.*
)。エラー管理: エラーページ(
server.error.path
)などの場所。
Spring Boot は、できる限り共通の設定を公開しようとしますが、常に可能であるとは限りません。そのような場合、専用の名前空間でサーバー固有のカスタマイズが提供されます (server.tomcat
および server.undertow
を参照)。たとえば、アクセスログは、埋め込みサーブレットコンテナーの特定の機能を使用して構成できます。
完全なリストについては、ServerProperties (Javadoc) クラスを参照してください。 |
SameSite クッキー
SameSite
cookie 属性は、クロスサイトリクエストで Cookie を送信するかどうか、および送信する方法を制御するために Web ブラウザーで使用できます。この属性は、属性が欠落しているときに使用されるデフォルト値を変更し始めた最新の Web ブラウザーに特に関係があります。
セッション Cookie の SameSite
属性を変更する場合は、server.servlet.session.cookie.same-site
プロパティを使用できます。このプロパティは、自動構成された Tomcat、Jetty、Undertow サーバーでサポートされています。また、Spring Session サーブレットベースの SessionRepository
Bean を構成するためにも使用されます。
例: セッション Cookie に None
の SameSite
属性を持たせたい場合は、application.properties
または application.yaml
ファイルに以下を追加できます。
プロパティ
YAML
server.servlet.session.cookie.same-site=none
server:
servlet:
session:
cookie:
same-site: "none"
HttpServletResponse
に追加された他の Cookie の SameSite
属性を変更する場合は、CookieSameSiteSupplier
を使用できます。CookieSameSiteSupplier
には Cookie
が渡され、SameSite
値または null
を返す場合があります。
特定の Cookie をすばやく照合するために使用できる便利なファクトリおよびフィルターメソッドがいくつかあります。例: 次の Bean を追加すると、正規表現 myapp.*
と一致する名前のすべての Cookie に Lax
の SameSite
が自動的に適用されます。
Java
Kotlin
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MySameSiteConfiguration {
@Bean
public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*");
}
}
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MySameSiteConfiguration {
@Bean
fun applicationCookieSameSiteSupplier(): CookieSameSiteSupplier {
return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*")
}
}
文字エンコード
リクエストおよびレスポンス処理のための組み込みサーブレットコンテナーの文字エンコード動作は、server.servlet.encoding.*
構成プロパティを使用して構成できます。
リクエストの Accept-Language
ヘッダーがリクエストのロケールを示す場合、サーブレットコンテナーによって自動的に文字セットにマッピングされます。各コンテナーにはデフォルトのロケールと文字セットのマッピングが用意されており、それらがアプリケーションのニーズを満たしていることを確認する必要があります。そうでない場合は、次の例に示すように、server.servlet.encoding.mapping
構成プロパティを使用してマッピングをカスタマイズします。
プロパティ
YAML
server.servlet.encoding.mapping.ko=UTF-8
server:
servlet:
encoding:
mapping:
ko: "UTF-8"
前述の例では、ko
(韓国語) ロケールが UTF-8
にマップされています。これは、従来の war デプロイの web.xml
ファイル内の <locale-encoding-mapping-list>
エントリに相当します。
プログラムによるカスタマイズ
組み込みサーブレットコンテナーをプログラムで設定する必要がある場合は、WebServerFactoryCustomizer
インターフェースを実装する Spring Bean を登録できます。WebServerFactoryCustomizer
は、多数のカスタマイズ setter メソッドを含む ConfigurableServletWebServerFactory
へのアクセスを提供します。次の例は、プログラムでポートを設定する方法を示しています。
Java
Kotlin
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory
import org.springframework.stereotype.Component
@Component
class MyWebServerFactoryCustomizer : WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
override fun customize(server: ConfigurableServletWebServerFactory) {
server.setPort(9000)
}
}
TomcatServletWebServerFactory
、JettyServletWebServerFactory
、UndertowServletWebServerFactory
は ConfigurableServletWebServerFactory
の専用バリアントであり、Tomcat、Jetty、Undertow 用にそれぞれ追加のカスタマイズ setter メソッドがあります。次の例は、Tomcat 固有の構成オプションへのアクセスを提供する TomcatServletWebServerFactory
をカスタマイズする方法を示しています。
Java
Kotlin
import java.time.Duration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory server) {
server.addConnectorCustomizers((connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
}
}
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component
import java.time.Duration
@Component
class MyTomcatWebServerFactoryCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
override fun customize(server: TomcatServletWebServerFactory) {
server.addConnectorCustomizers({ connector -> connector.asyncTimeout = Duration.ofSeconds(20).toMillis() })
}
}
ConfigurableServletWebServerFactory を直接カスタマイズする
ServletWebServerFactory
から拡張する必要があるより高度なユースケースの場合は、そのような型の Bean を自分で公開できます。
Setter は、多くの構成オプション用に提供されています。さらに特殊な操作が必要な場合に備えて、protected メソッド「フック」もいくつか提供されています。詳細については、ConfigurableServletWebServerFactory (Javadoc)
API ドキュメントを参照してください。
自動構成されたカスタマイザーは引き続きカスタムファクトリに適用されるため、そのオプションは慎重に使用してください。 |
JSP の制限
組み込みサーブレットコンテナーを使用する(実行可能アーカイブとしてパッケージ化されている)Spring Boot アプリケーションを実行する場合、JSP サポートにはいくつかの制限があります。
Jetty と Tomcat では、war パッケージを使用すれば動作するはずです。実行可能な war は、
java -jar
で起動すると動作し、任意の標準コンテナーに配備することもできます。実行可能 jar を使用する場合、JSP はサポートされません。Undertow は JSP をサポートしていません。
カスタム
error.jsp
ページを作成しても、エラー処理のデフォルトビューは上書きされません。代わりにカスタムエラーページを使用する必要があります。