Spring MVCは初めてです。ドキュメントの開梱を手伝ってください。
ドキュメント
Spring MVC Documentation states(emphasis mine):
メソッド引数の@ModelAttribute
は、モデルから引数を取得する必要があることを示します。モデルに存在しない場合は、引数を最初にインスタンス化してからモデルに追加する必要があります。モデルに表示されると、引数のフィールドは、一致する名前を持つすべてのリクエストパラメーターから入力されます。 WebDataBinderクラスは、要求パラメーター名と一致します-クエリ文字列パラメーターとフォームフィールドを含む———属性フィールドを名前でモデル化します。
@RequestParam
は、リクエストパラメーターをコントローラーのメソッドパラメーターにバインドします。
免責事項/クラリファイヤー
@ModelAttribute
と@RequestParam
は同じものではなく、相互に排他的ではなく、同じ役割を果たさず、同時に使用できることを知っています この質問 -実際、@RequestParam
を使用して入力できます@ModelAttribute
のフィールド。私の質問は、彼らの内部の働きの違いに向けられています。
質問:
@ModelAttribute
(メソッドではなくメソッド引数で使用される)と@RequestParam
の違いは何ですか?具体的には:
@RequestParam
と@ModelAttribute
の情報/母集団、つまりURLのリクエストパラメータは、フォームの要素として提供されている可能性がありますか/ POST
edされたモデル?@RequestParam
で取得された変数は(モデルに渡されない限り)捨てられますが、@ModelAttribute
で取得された変数はモデルに自動的に供給されますか?返される?または、非常に基本的なコーディング例では、これら2つの例の実際の動作上の違いは何ですか?
例1:@RequestParam
:
// foo and bar are thrown away, and are just used (e.g.) to control flow?
@RequestMapping(method = RequestMethod.POST)
public String testFooBar(@RequestParam("foo") String foo,
@RequestParam("bar") String bar, ModelMap model) {
try {
doStuff(foo, bar);
}
// other code
}
例2:@ModelAttribute
:
// FOOBAR CLASS
// Fields could of course be explicitly populated from parameters by @RequestParam
public class FooBar{
private String foo;
private String bar;
// plus set() and get() methods
}
// CONTROLLER
// Foo and Bar become part of the model to be returned for the next view?
@RequestMapping(method = RequestMethod.POST)
public String setupForm(@ModelAttribute("fooBar") FooBar foobar) {
String foo = fooBar.getFoo();
String bar = fooBar.getBar();
try {
doStuff(foo, bar);
}
// other code
}
私の現在の理解:
@ModelAttribute
と@RequestParam
は両方とも、要求パラメーターに情報を問い合わせますが、この情報の使い方は異なります。
@RequestParam
は、スタンドアロン変数(もちろん、@ModelAttribute
クラスのフィールド)を設定するだけです。これらの変数は、モデルに入力されていない限り、コントローラーが完了すると破棄されます。
@ModelAttribute
は、クラスのフィールドにデータを設定します。これにより、モデルの属性が設定され、ビューに戻されます
これは正しいです?
_
@RequestParam
_は、スタンドアロン変数(もちろん、_@ModelAttribute
_クラスのフィールドである可能性があります)を設定するだけです。これらの変数は、モデルに入力されていない限り、コントローラーが完了すると破棄されます。
Wordの「モデル」とセッションを混同しないでください。 httpの会話は通常、_HTTP.GET
_、サーバー応答、そして__HTTP.POST
_です。 _@ModelAttribute
_注釈を使用している場合、注釈を付けたもののインスタンスを常に構築しているので、「モデルに物を与える」ことで変数が固定される可能性があると思われます。 HttpServletRequest
が終了すると、これらの変数はセッションに保存されない限り、ブラウザー/サーバーの会話の一部ではなくなります。これは正しくありません。
_
@ModelAttribute
_は、クラスのフィールドにデータを設定し、ビューに返されるモデルの属性を設定します
はい!正確に言うと、_@ModelAttribute
_は、デフォルトのWebデータバインダーを使用してHttpServletRequest
からのデータをインスタンスに入力するようにSpringに指示します。このデータをビューに戻すことを選択するのはプログラマー次第です。 _@ModelAttribute
_アノテーションが付けられたメソッドがある場合、コードがそのサーブレットにヒットするたびに呼び出されます。メソッドのパラメーターの1つとして_@ModelAttribute
_がある場合、着信Httpフォームのデータバインディングについて説明しています。
_@RequestParam
_を呼び出すことは、request.getParameter("foo")
;を言うためのショートカットです。内部では、JavaのHttpServletRequest
を使用すると、キーから値へのルックアップを実行して、リクエストオブジェクトから値を取得できます。返される値はObject型です。これは、WebアプリケーションでSpringを使用していない場合によく入力するものです。
_@ModelAttribute
_の使用を開始すると、Springはこの抽象化をさらに一歩進めます。この注釈は、データバインディングの概念を採用しています。データバインディングの目標は、コントローラーのコードがすべてのフォーム要素に対してrequest.getParameter("foo1")
を呼び出す必要がないことです。 5つのフィールドを持つWebフォームがあるとします。データバインドを使用しない場合、プログラマはこれらの各フィールドを手動で取得して検証する必要があります。プログラマーは、リクエストにプロパティが含まれていること、プロパティの値が存在すること、およびプロパティの値が各フィールドに期待されるタイプであることを確認する必要があります。 _@ModelAttribute
_を使用すると、Springにこの作業を行うように指示されます。
コントローラーのメソッドに@ModelAttribute("fooBar") FooBar fooBar
アノテーションを付ける場合、FooBar
のインスタンスは、Springによってalwaysに構築され、メソッドに提供されます。データバインディングが機能するのは、このアノテーションがメソッドのパラメーターで使用されるときです。 SpringはHttpServletRequest
のインスタンスを調べ、FooBar
のインスタンスの適切なプロパティへのリクエストのデータと一致するかどうかを確認します。これはJavaプロパティの慣習に基づいています。ここでは、foo
などのフィールドと、getFoo
およびsetFoo
という名前のパブリックgetterおよびsetterがあります。これは魔法のように思えるかもしれませんが、慣習に違反すると、SpringデータバインディングはHttpServletRequest
からのデータをバインドするためにwhereを知ることができないため、動作を停止します。は引き続きFooBar
のインスタンスを取得しますが、プロパティはリクエストからの値に設定されません。
@ModelAttribute
:Javaオブジェクト(Employeeなど)全体をバインドします。複数の要求パラメーターをサポートします。
@RequestParam
:単一の要求パラメーター(firstNameなど)をバインドします
一般に、@RequestParam
は、少数のパラメーターを読み取るのに最適です。
@ModelAttribute
は、多数のフィールドを持つフォームがある場合に使用されます。
そして
@ModelAttribute
は、データバインディング、検証、フォームの事前入力などの追加機能を提供します。
@ModelAttribute
注釈付きパラメーターは登録済みServletModelAttributeMethodProcessor
(またはModelAttributeMethodProcessor
)によって処理され、@RequestParam
注釈付きパラメーターは登録済みRequestParamMethodArgumentResolver
またはRequestParamMapMethodArgumentResolver
によって処理されますパラメータタイプ。
ここでは、SpringがこれらのHandlerMethodArgumentResolvers
を使用してハンドラーメソッドの引数を解決する方法について説明します。
両方の場合、@ModelAttribute
および@RequestParam
の場合、バインドされる値は ServletRequest
parameters から取得されます。
上記のタイプのソースコードを見ることができますが、簡単な詳細を以下に示します。
@ModelAttribute
の場合、Springはパラメータータイプのインスタンスを作成します。そのインスタンスのフィールドを検査し、@ModelAttribute
名とフィールド名で構成される命名/エイリアス戦略に基づいてパラメーター値をそれらにバインドしようとします。通常、Converter
インスタンスのグループを使用して、String
(パラメーター値は常にString
値)からターゲットフィールドタイプInteger
、Date
、独自のConverter
型をカスタム変換用に登録することもできます。 POJO型をネストすることもできます。
@RequestParam
の場合、Springは同じConverter
インスタンスを使用して、パラメーター値から注釈付きパラメータータイプに直接変換します。
パラメーター値は「破棄」されないことに注意してください。それらは、コンテナのリクエスト処理サイクルの間、HttpServletRequest
に保存されます。 適切なメソッド でいつでもアクセスできます。
@ModelAttribute
(parameter)は、@SessionAttributes
または@ModelAttribute
(method)からモデル属性をロードします。
リクエストの値をバインドするためだけに必要ではありませんが、@SessionAttributes
からロードした後にバインドします。
@RequestParam
は、リクエストパラメータをオブジェクトにバインドします。