Model

@ModelAttribute アノテーションを使用できます。

  • @RequestMapping メソッドのメソッド引数で、モデルからオブジェクトを作成またはアクセスし、それを WebDataBinder を通じてリクエストにバインドします。

  • @Controller または @ControllerAdvice クラスのメソッドレベルのアノテーションとして、@RequestMapping メソッドを呼び出す前にモデルを初期化できます。

  • @RequestMapping メソッドで、戻り値をモデル属性としてマークします。

このセクションでは、@ModelAttribute メソッド、または前述のリストの 2 番目の項目について説明します。コントローラーは、@ModelAttribute メソッドをいくつでも持つことができます。このようなメソッドはすべて、同じコントローラー内の @RequestMapping メソッドの前に呼び出されます。@ModelAttribute メソッドは、@ControllerAdvice を介してコントローラー間で共有することもできます。詳細については、コントローラーのアドバイスのセクションを参照してください。

@ModelAttribute メソッドには、柔軟なメソッドシグネチャーがあります。これらは、@RequestMapping メソッドと同じ引数の多くをサポートします(@ModelAttribute 自体とリクエスト本文に関連するものを除く)。

次の例では、@ModelAttribute メソッドを使用しています。

  • Java

  • Kotlin

@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
	model.addAttribute(accountRepository.findAccount(number));
	// add more ...
}
@ModelAttribute
fun populateModel(@RequestParam number: String, model: Model) {
	model.addAttribute(accountRepository.findAccount(number))
	// add more ...
}

次の例では、1 つの属性のみを追加します。

  • Java

  • Kotlin

@ModelAttribute
public Account addAccount(@RequestParam String number) {
	return accountRepository.findAccount(number);
}
@ModelAttribute
fun addAccount(@RequestParam number: String): Account {
	return accountRepository.findAccount(number);
}
名前が明示的に指定されていない場合、Conventions (Javadoc) の javadoc に従って、型に基づいてデフォルト名が選択されます。オーバーロードされた addAttribute メソッドを使用するか、@ModelAttribute の name 属性(戻り値用)を使用して、明示的な名前をいつでも割り当てることができます。

Spring WebFlux は、Spring MVC とは異なり、モデルでリアクティブ型を明示的にサポートします (たとえば、Mono<Account> または io.reactivex.Single<Account>)。このような非同期モデル属性は、次の例に示すように、@ModelAttribute 引数がラッパーなしで宣言されている場合、@RequestMapping 呼び出し時に実際の値に透過的に解決 (およびモデルを更新) できます。

  • Java

  • Kotlin

@ModelAttribute
public void addAccount(@RequestParam String number) {
    Mono<Account> accountMono = accountRepository.findAccount(number);
    model.addAttribute("account", accountMono);
}

@PostMapping("/accounts")
public String handle(@ModelAttribute Account account, BindingResult errors) {
	// ...
}
import org.springframework.ui.set

@ModelAttribute
fun addAccount(@RequestParam number: String) {
	val accountMono: Mono<Account> = accountRepository.findAccount(number)
	model["account"] = accountMono
}

@PostMapping("/accounts")
fun handle(@ModelAttribute account: Account, errors: BindingResult): String {
	// ...
}

さらに、リアクティブ型ラッパーを持つモデル属性は、ビューのレンダリングの直前に実際の値に解決されます(そしてモデルが更新されます)。

@ModelAttribute を @RequestMapping メソッドのメソッドレベルのアノテーションとして使用することもできます。その場合、@RequestMapping メソッドの戻り値はモデル属性として解釈されます。戻り値がビュー名として解釈される String でない限り、これは HTML コントローラーのデフォルトの動作であるため、通常は必要ありません。@ModelAttribute は、次の例に示すように、モデル属性名のカスタマイズにも役立ちます。

  • Java

  • Kotlin

@GetMapping("/accounts/{id}")
@ModelAttribute("myAccount")
public Account handle() {
	// ...
	return account;
}
@GetMapping("/accounts/{id}")
@ModelAttribute("myAccount")
fun handle(): Account {
	// ...
	return account
}