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 内) で説明されています。
列挙型 | プロパティ | 値 |
---|---|---|
|
| |
|
| |
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
例: プリティプリントを有効にするには、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] (英語) を参照してください。
サーブレットコンテナーにハンドラーを登録する方法の詳細については、エラー処理のセクションも参照してください。