Spring MVC

Spring Boot には、Spring MVC を含む多くのスターターがあります。一部のスターターには、直接ではなく Spring MVC への依存関係が含まれていることに注意してください。このセクションでは、Spring MVC および Spring Boot に関するよくある質問に回答します。

JSON REST サービスを作成する

次の例に示すように、Spring Boot アプリケーション内のすべての Spring @RestController (Javadoc) は、Jackson 3 がクラスパス上にある限り、デフォルトで JSON レスポンスをレンダリングする必要があります。

  • Java

  • Kotlin

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

	@RequestMapping("/thing")
	public MyThing thing() {
		return new MyThing();
	}

}
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class MyController {

	@RequestMapping("/thing")
	fun thing(): MyThing {
		return MyThing()
	}

}

MyThing が Jackson 3 で直列化できる限り(通常の POJO または Groovy オブジェクトの場合)、localhost:8080/thing はデフォルトで JSON 表現で返します。ブラウザーでは XML を優先する Accept ヘッダーを送信する傾向があるため、XML レスポンスが表示される場合があることに注意してください。

XML REST サービスを作成する

クラスパスに Jackson XML 拡張(jackson-dataformat-xml)がある場合、それを使用して XML レスポンスをレンダリングできます。JSON に使用した前の例は機能します。Jackson XML レンダラーを使用するには、次の依存関係をプロジェクトに追加します。

<dependency>
	<groupId>tools.jackson.dataformat</groupId>
	<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Jackson の XML 拡張機能が利用できず、JAXB が利用できる場合は、次の例に示すように、MyThing を @XmlRootElement (英語) としてアノテーション付けするという追加要件で XML をレンダリングできます。

  • Java

  • Kotlin

import jakarta.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class MyThing {

	private String name;

	// getters/setters ...

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
import jakarta.xml.bind.annotation.XmlRootElement

@XmlRootElement
class MyThing {

	var name: String? = null

}

たとえば、次を追加して、JAXB ライブラリがプロジェクトの一部であることを確認する必要があります。

<dependency>
	<groupId>org.glassfish.jaxb</groupId>
	<artifactId>jaxb-runtime</artifactId>
</dependency>
サーバーに JSON ではなく XML をレンダリングさせるには、Accept: text/xml ヘッダーを送信する(またはブラウザーを使用する)必要があります。

Jackson JsonMapper をカスタマイズする

JsonMapper (英語) は環境設定を使って設定できます。Jackson は、処理の様々な側面を設定するための広範なオン / オフ機能を提供しています。これらの機能は、環境内のプロパティにマッピングされるいくつかの列挙型(Jackson 内)で記述されています。

列挙型 プロパティ

DateTimeFeature (英語)

spring.jackson.datatype.datetime.<feature_name>

true, false

EnumFeature (英語)

spring.jackson.datatype.enum.<feature_name>

true, false

JsonNodeFeature (英語)

spring.jackson.datatype.json-node.<feature_name>

true, false

JsonInclude.Include (英語)

spring.jackson.default-property-inclusion

always, non_null, non_absent, non_default, non_empty

DeserializationFeature (英語)

spring.jackson.deserialization.<feature_name>

true, false

JsonReadFeature (英語)

spring.jackson.json.read.<feature_name>

true, false

JsonWriteFeature (英語)

spring.jackson.json.write.<feature_name>

true, false

MapperFeature (英語)

spring.jackson.mapper.<feature_name>

true, false

SerializationFeature (英語)

spring.jackson.serialization.<feature_name>

true, false

例: プリティプリントを有効にするには、spring.jackson.serialization.indent_output=true を設定します。緩いバインディングの使用のおかげで、indent_output の大文字と小文字は、対応する enum 定数 ( INDENT_OUTPUT) の大文字と小文字が一致する必要がないことに注意してください。

この環境ベースの構成は、自動構成された JsonMapper.Builder (英語) Bean に適用され、自動構成された JsonMapper (英語) Bean を含む、ビルダーを使用して作成されたすべてのマッパーに適用されます。

以前 Jackson 2 を使用していたアプリケーションで作業する場合、移行を容易にするために、自動構成された JsonMapper を、Spring Boot が Jackson 2 に使用していたデフォルト設定に可能な限り近い設定を使用するように設定できます。これらのデフォルト設定を有効にするには、spring.jackson.use-jackson2-defaults を true に設定します。

コンテキストの JsonMapper.Builder (英語) は、1 つ以上の JsonMapperBuilderCustomizer (Javadoc) Bean でカスタマイズできます。これらのカスタマイザ Bean は順序付けが可能で(Boot 自身のカスタマイザの順序は 0)、Boot のカスタマイズの前後に追加のカスタマイズを適用できます。さらに、ビルダーとそれが作成するマッパーで使用される JsonFactory は、1 つ以上の JsonFactoryBuilderCustomizer (Javadoc) Bean でカスタマイズできます。また、spring.jackson.factory の各種プロパティを使用してファクトリを構成することもできます。

JacksonModule (英語) 型の Bean はすべて、自動構成された JsonMapper.Builder (英語) に自動的に登録され、JsonMapper.Builder (英語) が生成するすべての JsonMapper (英語) インスタンスに適用されます。これにより、アプリケーションに新しい機能を追加する際に、カスタムモジュールを提供するためのアプリケーション全体のメカニズムが提供されます。

Java ServiceLoader メカニズムに参加するモジュールは、デフォルトで検出され、自動構成された JsonMapper.Builder (英語) に追加されます。この動作を無効にするには、spring.jackson.find-and-add-modules を false に設定してください。

デフォルトの JsonMapper (英語) を完全に置き換える場合は、その型の @Bean (Javadoc) を定義するか、ビルダーベースのアプローチを好む場合は JsonMapper.Builder (英語) @Bean (Javadoc) を定義します。JsonMapper (英語) Bean を定義するときは、置き換えられる自動構成の JsonMapper (英語) @Primary (Javadoc) であるため、@Primary (Javadoc) としてマークすることをお勧めします。どちらの場合でも、これを行うと JsonMapper (英語) のすべての自動構成が無効になることに注意してください。

JacksonJsonHttpMessageConverter (Javadoc) 型の @Bean (Javadoc) を指定した場合、MVC 構成のデフォルト値が置き換えられます。また、HttpMessageConverters (Javadoc) 型の便利な Bean も提供されています(デフォルトの MVC 構成を使用する場合は常に利用可能です)。この Bean には、デフォルトおよびユーザー定義のメッセージコンバーターにアクセスするための便利なメソッドがいくつか用意されています。

詳細については、@ResponseBody レンダリングのカスタマイズセクションと WebMvcAutoConfiguration [GitHub] (英語) ソースコードを参照してください。

@ResponseBody レンダリングのカスタマイズ

Spring は、HttpMessageConverters (Javadoc) を使用して @ResponseBody (Javadoc) (または @RestController (Javadoc) からのレスポンス) をレンダリングします。Spring Boot コンテキストに適切な型の Bean を追加することで、追加のコンバーターを提供できます。追加した Bean がデフォルトで含まれている型 (JSON 変換の JacksonJsonHttpMessageConverter (Javadoc) など) である場合は、デフォルト値が置き換えられます。型 HttpMessageConverters (Javadoc) の便利な Bean が提供されており、デフォルトの MVC 構成を使用する場合は常に使用できます。これには、デフォルトおよびユーザー拡張メッセージコンバーターにアクセスするための便利なメソッドがいくつかあります (例: カスタム RestTemplate (Javadoc) に手動で挿入する場合に便利です)。

通常の MVC の使用と同様に、提供する WebMvcConfigurer (Javadoc) Bean は、configureMessageConverters メソッドをオーバーライドすることでコンバーターを提供することもできます。ただし、通常の MVC とは異なり、必要な追加のコンバーターのみを提供できます (Spring Boot は同じメカニズムを使用してデフォルトを提供するため)。最後に、独自の @EnableWebMvc (Javadoc) 構成を提供することでデフォルトの Spring Boot MVC 構成をオプトアウトすると、WebMvcConfigurationSupport (Javadoc) の getMessageConverters を使用して完全に制御し、すべてを手動で実行できます。

詳細については、WebMvcAutoConfiguration [GitHub] (英語) ソースコードを参照してください。

マルチパートファイルのアップロードの処理

Spring Boot は、ファイルのアップロードをサポートするために、サーブレット 5 Part (英語) API を採用しています。デフォルトでは、Spring Boot は、1 ファイルあたり最大 1 MB、1 回のリクエストで最大 10 MB のファイルデータで Spring MVC を構成します。これらの値、中間データの保存場所 (たとえば、/tmp ディレクトリ)、およびデータがディスクにフラッシュされるしきい値は、MultipartProperties (Javadoc) クラスで公開されているプロパティを使用してオーバーライドできます。たとえば、ファイルを無制限に指定する場合は、spring.servlet.multipart.max-file-size プロパティを -1 に設定します。

マルチパートサポートは、Spring MVC コントローラーハンドラーメソッドで、MultipartFile (Javadoc) 型の @RequestParam (Javadoc) アノテーション付きパラメーターとしてマルチパートでエンコードされたファイルデータを受信する場合に役立ちます。

詳細については、MultipartAutoConfiguration [GitHub] (英語) ソースを参照してください。

Apache Commons ファイルアップロードなどの追加の依存関係を導入するのではなく、コンテナーに組み込まれているマルチパートアップロードのサポートを使用することをお勧めします。

Spring MVC DispatcherServlet をオフにする

デフォルトでは、すべてのコンテンツはアプリケーションのルート(/)から提供されます。別のパスにマップする場合は、次のように構成できます。

  • プロパティ

  • YAML

spring.mvc.servlet.path=/mypath
spring:
  mvc:
    servlet:
      path: "/mypath"

追加のサーブレットがある場合は、それぞれに Servlet (英語) または ServletRegistrationBean (Javadoc) 型の @Bean (Javadoc) を宣言できます。Spring Boot はそれらをコンテナーに透過的に登録します。また、ServletRegistrationBean (Javadoc) のアノテーションベースの代替として @ServletRegistration (Javadoc) を使用することもできます。このようにサーブレットが登録されるため、DispatcherServlet (Javadoc) を呼び出すことなく、そのサブコンテキストにマッピングできます。

DispatcherServletPath (Javadoc) を自分で構成することは珍しいことですが、本当に必要な場合は、カスタム DispatcherServlet (Javadoc) のパスを指定するために、型 DispatcherServletPath (Javadoc) @Bean (Javadoc) も提供する必要があります。

デフォルトの MVC 構成をオフにする

MVC 構成を完全に制御する最も簡単な方法は、@EnableWebMvc (Javadoc) アノテーションを使用して独自の @Configuration (Javadoc) を提供することです。これにより、すべての MVC 構成を自分で管理できるようになります。

ViewResolvers をカスタマイズする

ViewResolver (Javadoc) は Spring MVC のコアコンポーネントであり、@Controller (Javadoc) のビュー名を実際の View (Javadoc) 実装に変換します。ビューリゾルバーは主に UI アプリケーションで使用され、REST スタイルのサービスでは使用されないことに注意してください (View (Javadoc) @ResponseBody (Javadoc) のレンダリングには使用されません)。選択できる ViewResolver (Javadoc) の実装は多数あり、Spring 自体はどの実装を使用すべきかについて明確な見解を持っていません。一方、Spring Boot は、クラスパスとアプリケーションコンテキストで見つかったものに応じて、1 つまたは 2 つのリゾルバーをインストールします。DispatcherServlet (Javadoc) は、アプリケーションコンテキストで見つかったすべてのリゾルバーを使用し、結果が得られるまで 1 つずつ順番に試します。独自のリゾルバーを追加する場合は、リゾルバーが追加される順序と位置に注意する必要があります。

WebMvcAutoConfiguration (Javadoc) は、次の ViewResolver (Javadoc) Bean をコンテキストに追加します。

  • "defaultViewResolver" という名前の InternalResourceViewResolver (Javadoc) 。これは、DefaultServlet を使用してレンダリングできる物理リソース (使用している場合は静的リソースと JSP ページを含む) を検索します。ビュー名にプレフィックスとサフィックスを適用し、サーブレットコンテキストでそのパスを持つ物理リソースを検索します (デフォルトでは両方とも空ですが、spring.mvc.view.prefix および spring.mvc.view.suffix を介して外部構成にアクセスできます)。同じ型の Bean を提供することで、これをオーバーライドできます。

  • "beanNameViewResolver" という名前の BeanNameViewResolver (Javadoc) 。これはビューリゾルバーチェーンの便利なメンバーであり、解決される View (Javadoc) と同じ名前を持つすべての Bean を取得します。これをオーバーライドしたり置き換えたりする必要はありません。

  • 'viewResolver' という名前の ContentNegotiatingViewResolver (Javadoc) は、実際に View (Javadoc) 型の Bean が 存在する場合にのみ追加されます。これは複合リゾルバーであり、他のすべてのリゾルバーに委譲し、クライアントから送信された 'Accept' HTTP ヘッダーに一致するものを見つけようとします。さらに詳しく知るには、役に立つ ContentNegotiatingViewResolver (英語) についてのブログを学習するとよいかもしれません。また、ソースコードで詳細を確認することもできます。'viewResolver' という名前の Bean を定義すると、自動構成された ContentNegotiatingViewResolver (Javadoc) をオフにできます。

  • Thymeleaf を使用する場合は、"thymeleafViewResolver" という名前の ThymeleafViewResolver (英語) も存在します。ビュー名をプレフィックスとサフィックスで囲んでリソースを検索します。プレフィックスは spring.thymeleaf.prefix、サフィックスは spring.thymeleaf.suffix です。プレフィックスとサフィックスの値は、それぞれデフォルトで "classpath:/templates/" と ".html" になります。同じ名前の Bean を提供することで、ThymeleafViewResolver (英語) をオーバーライドできます。

  • FreeMarker を使用する場合は、"freeMarkerViewResolver" という名前の FreeMarkerViewResolver (Javadoc) もあります。これは、ビュー名をプレフィックスとサフィックスで囲むことで、ローダーパス (spring.freemarker.templateLoaderPath に外部化され、デフォルト値は "classpath:/templates/" ) 内のリソースを検索します。プレフィックスは spring.freemarker.prefix に外部化され、サフィックスは spring.freemarker.suffix に外部化されます。プレフィックスとサフィックスのデフォルト値は、それぞれ空と ".ftlh" です。同じ名前の Bean を提供することで、FreeMarkerViewResolver (Javadoc) をオーバーライドできます。FreeMarker 変数は、型 FreeMarkerVariablesCustomizer (Javadoc) の Bean を定義することでカスタマイズできます。

  • Groovy テンプレートを使用する場合 (実際には、groovy-templates がクラスパス上にある場合)、"groovyMarkupViewResolver" という名前の GroovyMarkupViewResolver (Javadoc) もあります。ビュー名をプレフィックスとサフィックス (spring.groovy.template.prefix と spring.groovy.template.suffix に外部化) で囲むことで、ローダーパス内のリソースを検索します。プレフィックスとサフィックスのデフォルト値は、それぞれ "classpath:/templates/" と ".tpl" です。同じ名前の Bean を提供することで、GroovyMarkupViewResolver (Javadoc) をオーバーライドできます。

  • Mustache を使用する場合は、"mustacheViewResolver" という名前の MustacheViewResolver (Javadoc) も存在します。ビュー名をプレフィックスとサフィックスで囲んでリソースを検索します。プレフィックスは spring.mustache.prefix、サフィックスは spring.mustache.suffix です。プレフィックスとサフィックスの値は、それぞれデフォルトで "classpath:/templates/" と ".mustache" になります。同じ名前の Bean を提供することで、MustacheViewResolver (Javadoc) をオーバーライドできます。

詳細については、次のセクションを参照してください。

「ホワイトラベル」エラーページをカスタマイズする

Spring Boot は、サーバーエラーが発生した場合にブラウザークライアントに表示される「ホワイトラベル」エラーページをインストールします(JSON およびその他のメディア型を使用するマシンクライアントは、適切なエラーコードで適切なレスポンスを確認する必要があります)。

デフォルトのエラーページを無効にするには、spring.web.error.whitelabel.enabled を false に設定します。これにより、使用しているサーブレットコンテナーのデフォルト設定が復元されます。ただし、Spring Boot は引き続きエラービューの解決を試行するため、完全に無効にするのではなく、独自のエラーページを追加することをお勧めします。

エラーページを独自のものに上書きする方法は、使用するテンプレートテクノロジによって異なります。例: Thymeleaf を使用する場合は、error.html テンプレートを追加できます。FreeMarker を使用する場合は、error.ftlh テンプレートを追加できます。一般的には、error という名前で解決される View (Javadoc) または /error パスを処理する @Controller (Javadoc) が必要です。デフォルト構成の一部を置き換えていない限り、ApplicationContext (Javadoc) 内に BeanNameViewResolver (Javadoc) があるはずなので、error という名前の @Bean (Javadoc) がその 1 つの方法です。その他のオプションについては、ErrorMvcAutoConfiguration [GitHub] (英語) を参照してください。

サーブレットコンテナーにハンドラーを登録する方法の詳細については、エラー処理のセクションも参照してください。