2016-06-23 7 views
2

私はSpring MVCを初めて使用しています。いくつかのアプリを稼働させるために管理されていますが、私はいくつかの方向でどのように動作するかに疑問を抱いていますし、私が探している説明を見つけることができません。特に、この方法では:モデルの解像度の仕組みの理解

@Controller 
@RequestMapping("/hello") 
public class HelloController{ 

    @RequestMapping(method = RequestMethod.GET) 
    public String printHello(ModelMap model) { 
     model.addAttribute("message", "Hello Spring MVC Framework!"); 
     return "hello"; 
    } 

} 

私は(名前message下)"Hello Spring MVC Framework!"がビューに渡されている知っています。しかし、私には関係して少し珍しい見つける二つのものがあります:

  1. はなぜmodelprintHello方法に入力パラメータとして宣言されていますか?ローカル変数としては言いませんか?
  2. modelは、の明示的に渡されています。
+0

DispatcherServletがHandlerMappingを参照して適切なControllerを呼び出すとき、おそらくそれはオブジェクトをメソッドの引数に渡すように、それ自身のModelMapオブジェクトを構築すると考えています。また、ローカルインスタンシエーションで明示的に構築すると、オブジェクトはハンドラによって管理されないため、バインディングは発生しません。したがって、それを慣例/合意として考えることができます。 –

答えて

2

なぜmodelprintHelloメソッドへの入力パラメータとして宣言されていますか?ローカル変数としては言いませんか?

あなたはローカル変数として宣言し、必要ならばそれを返すことができます。

@RequestMapping("/hello") 
public ModelMap printHello() { 
    return new ModelMap("message", "Hello Spring MVC Framework!"); 
} 

しかし、あなたはSpringのデータバインディング(バインディング要求属性(GETリクエストのクエリパラメータ)を利用していないこの方法モデル化する)。

また、Spring MVCのは、論理ビュー名としてControllerサフィックスなしでコントローラ名を使用するデフォルトのDefaultRequestToViewNameTranslatorを使用して、それを推測しますので、あなたは、(あなたの元の例return "hello"のように)任意のビュー名を提供していないこの方法は、(あなたの例では、それはhelloになりますあなたのコントローラはHelloControllerです)。詳細は、documentationを参照してください。

さらに、ModelまたはModelMapではなく、新しいModelAndViewインスタンスを返すことができます。この場合、ビュー名とモデル属性を明示的に設定することができます。

しかし、ハンドラメソッドの引数としてModelを使用する主な利点は、データバインディングです。

あなたがメソッドの引数としてモデル(への要求をバインドする)いくつかのモデル属性を提供する場合、あなたはすでに追加してモデルインスタンスを取得(とリクエストパラメータを用いて充填)モデル属性モデルにして、あなたが追加することができますあなたがそれを必要とするならば、それに別の属性。

@RequestMapping(path = "/hello", method = RequestMethod.GET) 
public String printHello(Model model, @ModelAttribute("form") SearchForm form, BindingResult result) { 
    model.addAttribute("anotherUsefulValue", myService.getSomeValue()); 
    // 'hello' view will get the model with both 'form' and 'anotherUsefulValue' attributes 
    // and 'form' attribute will have 'text' field filled from request's 
    // query parameter 'text'. 
    return "hello"; 
} 

class SearchForm { 
    private String text; 
    // ... getter and setter 
} 

この方法を使用すると、textという名前のテキストフィールドを持つ一部のHTML formからの要求をGET行うことができますし、このフォームを送信すると、あなたのモデルは、値としてインスタンス化さSearchFormオブジェクトの属性formが含まれます。このオブジェクトのフィールドtextは、値としてtextクエリパラメータを持ちます。

spring-form JSP Tag Libraryを使用した例:

<form:form method="GET" action="/hello" modelAttribute="form"> 
    <form:input path="text" /> 
    <input type="submit"> 
</form> 

それともURL /hello?text=12345を入力してください。 modelform属性のtextフィールドは12345となり、の属性にはanotherUsefulValue属性も含まれます。 Springのデータバインディングとカスタムモデルの属性を組み合わせただけです。

もちろん、新しいモデルを手動で作成し、form属性とともにanotherUsefulValueをメソッドのform引数から設定することができます。しかし、それは単なる定型文です。

modelどこビュー明示的に渡さされていないが、これは何とか舞台裏起こるのでしょうか?

もちろんです。春のDispatcherServletは他の多くのものと同じようにこれを行います。これはすべてdocumentationに記載されています。

The request processing workflow in Spring Web MVC (high level)

Front Controllerちょうどあなたのコントローラメソッドが返されたかを知ると、それは新しいモデルであるか、あなたの方法ですべてのモデルを返さないし、その後Front Controllerが、それは引数としてお使いのコントローラメソッドに渡されたモデルを使用している場合に理解することができます。

1

あなたが提供してきました@RequestMapping注釈はこの魔法ありません。私はリテラルと比喩の両方の意味でそれを言う。それは基本的にすべてが必要とする混乱の手配を省略します。

  1. モデルは、多くオプションの入力パラメータの一つです。あなたが望むのであれば、より多くの、より少ない、または少ないものを提供することができます。この場合、ModalMapを使用したいので、引数をインクルードして "ModalMapを使用します"と言います。ヘッダーなどのリクエストからの引数がある場合は、それらを追加してキャストすることができます。

  2. これは、Springによって@Autowireに似ています。あなたがサービスをオートワイヤーすると、どこでも明示的にnew FooService()と言うことはできませんが、自動的に作成され、Springによって管理されます。あなたは、基本的には春に配線作業のほとんどをオフロードしている、とあなたは、あなたがそれを処理する必要が正確に何を扱う一方で、それはすべての定型を処理します。この場合

、あなたはget要求からクライアントに価値を持つModalMapを渡している、そしてその値がページにロードされます。

その他の情報+出典:それはローカル変数ではありません、なぜすべてのrequest.Thatための春MVCフレームワークによって作成されたhttp://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html

+0

私のポイントは:(1)入力パラメータとしてモデルを見るのは奇妙でした。(2)明示的にビューに渡されることはありません。 PS。この場合も、ビューに表示されるのは、コードで提示されたテキストだけです。したがって、他のデータは受信されていないと仮定します。 GETで –

+1

#2に関しては、これに似ています。 'Foo foo = new Foo(); String s = doSomething(foo); 'この場合、Springはまだ' foo'への参照を持っています。 'foo'はページを読み込むのに役立つところまで返される必要はありません。マッピングされた唯一の 'GET'メソッドであるため、argを持たないので、あなたが望むものであれメソッドを呼び出すことができ、依然としてレスポンスのターゲットメソッドになります。 – Compass

0

新しいmodelオブジェクトです。フレームワークによって作成されたオブジェクト自体はすでに参照を持っているので、フレームワークはそれをビューに渡します。私はあなたのコードに以下を追加HttpServletRequestオブジェクトに似引数として渡さmodelオブジェクトの

1

と思います。スプリングは、JSPに利用可能である暗黙requestオブジェクトと同様要求のライフサイクル全体にわたって利用可能である暗黙的なモデルオブジェクトを生成します。したがって、単一リクエストライフサイクルごとに、この暗黙のモデルオブジェクトはコントローラとビュー全体で共有されます。

@Controller 
@RequestMapping("/hello") 
public class HelloController{ 

    @RequestMapping(method = RequestMethod.GET) 
    public String printHello(ModelMap model, HttpServletRequest req) { 
     model.addAttribute("message", "Hello Spring MVC Framework!"); 
     return "hello"; 
    } 

} 

以下はspring docsの説明です。どこには、Webビューに をさらされる暗黙のモデルを豊かにするために

マップ/モデル/ ModelMapを@RequestMappingと注釈付きメソッドに渡された入力のparamsの意義は何か言及されています。

関連する問題