Spring MVC

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

JSON REST サービスを作成する

次の例に示すように、Jackson2 がクラスパス上にある限り、Spring Boot アプリケーション内のすべての Spring @RestController (Javadoc) はデフォルトで 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()
	}

}

Jackson2 が MyThing を直列化できる限り(通常の POJO または Groovy オブジェクトの場合は true)、localhost:8080/thing はデフォルトで JSON 表現を提供します。ブラウザーは XML を好む Accept ヘッダーを送信する傾向があるため、ブラウザーでは XML レスポンスが表示されることがあります。

XML REST サービスを作成する

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

<dependency>
	<groupId>com.fasterxml.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 ObjectMapper をカスタマイズする

Spring MVC (クライアント側とサーバー側) は、HTTP 交換でコンテンツ変換をネゴシエートするために HttpMessageConverters (Javadoc) を使用します。Jackson がクラスパス上にある場合は、Jackson2ObjectMapperBuilder (Javadoc) によって提供されるデフォルトのコンバーターがすでに取得されており、そのインスタンスは自動的に構成されます。

ObjectMapper (英語) (または Jackson XML コンバーターの場合は XmlMapper (英語) ) インスタンス (デフォルトで作成) には、次のカスタマイズされたプロパティがあります。

  • MapperFeature.DEFAULT_VIEW_INCLUSION は無効です

  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES は無効です

  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS は無効です

  • SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS は無効です

Spring Boot には、この動作を簡単にカスタマイズできるいくつかの機能もあります。

環境を使用して、ObjectMapper (英語) および XmlMapper (英語) インスタンスを構成できます。Jackson は、処理のさまざまなアスペクトを構成するために使用できる、広範なオン / オフ機能スイートを提供します。これらの機能は、環境内のプロパティにマップされるいくつかの列挙型 (Jackson 内) で説明されています。

列挙型 プロパティ

EnumFeature (英語)

spring.jackson.datatype.enum.<feature_name>

true, false

JsonNodeFeature (英語)

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

true, false

DeserializationFeature (英語)

spring.jackson.deserialization.<feature_name>

true, false

com.fasterxml.jackson.core.JsonGenerator.Feature

spring.jackson.generator.<feature_name>

true, false

MapperFeature (英語)

spring.jackson.mapper.<feature_name>

true, false

com.fasterxml.jackson.core.JsonParser.Feature

spring.jackson.parser.<feature_name>

true, false

SerializationFeature (英語)

spring.jackson.serialization.<feature_name>

true, false

com.fasterxml.jackson.annotation.JsonInclude.Include

spring.jackson.default-property-inclusion

always, non_null, non_absent, non_default, non_empty

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

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

コンテキストの Jackson2ObjectMapperBuilder (Javadoc) は、1 つ以上の Jackson2ObjectMapperBuilderCustomizer (Javadoc) Bean によってカスタマイズできます。このようなカスタマイザ Bean は順序付けが可能 (Boot 独自のカスタマイザの順序は 0) なので、Boot のカスタマイズの前後に追加のカスタマイズを適用できます。

Module (英語) 型の Bean はすべて、自動構成された Jackson2ObjectMapperBuilder (Javadoc) に自動的に登録され、作成される ObjectMapper (英語) インスタンスに適用されます。これにより、アプリケーションに新しい機能を追加するときにカスタムモジュールを提供するグローバルメカニズムが提供されます。

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

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

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

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

Spring は、HttpMessageConverters (Javadoc) を使用して @ResponseBody (Javadoc) (または @RestController (Javadoc) からのレスポンス) をレンダリングします。Spring Boot コンテキストに適切な型の Bean を追加することで、追加のコンバーターを提供できます。追加した Bean がデフォルトで含まれている型 (JSON 変換の MappingJackson2HttpMessageConverter (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 はそれらをコンテナーに透過的に登録します。サーブレットはこのように登録されるため、DispatcherServlet (Javadoc) を呼び出さずに、そのサブコンテキストにマップできます。

DispatcherServlet (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 およびその他のメディア型を使用するマシンクライアントは、適切なエラーコードで適切なレスポンスを確認する必要があります)。

server.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] (英語) を参照してください。

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