web-dev-qa-db-ja.com

@SessionAttributesの使用方法について混乱しています

SpringMVCのアーキテクチャを理解しようとしています。ただし、@ SessionAttributesの動作に完全に混乱しています。

以下のSampleControllerをご覧ください。SuperFormクラスによるpostメソッドを処理しています。実際、SuperFormクラスのフィールドだけが、私が期待したとおりにバインドされているだけです。

ただし、@ SessionAttributesをControllerに配置した後、処理メソッドはSubAFormとしてバインドされます。このバインディングで何が起こったのか誰かが私に説明できますか?.

-------------------------------------------------------

@Controller
@SessionAttributes("form")
@RequestMapping(value = "/sample")
public class SampleController {

    @RequestMapping(method = RequestMethod.GET)
    public String getCreateForm(Model model) {
        model.addAttribute("form", new SubAForm());
        return "sample/input";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String register(@ModelAttribute("form") SuperForm form, Model model) {
        return "sample/input";
    }
}

-------------------------------------------------------

public class SuperForm {

    private Long superId;

    public Long getSuperId() {
        return superId;
    }

    public void setSuperId(Long superId) {
        this.superId = superId;
    }

}

-------------------------------------------------------

public class SubAForm extends SuperForm {

    private Long subAId;

    public Long getSubAId() {
        return subAId;
    }

    public void setSubAId(Long subAId) {
        this.subAId = subAId;
    }

}

-------------------------------------------------------

<form:form modelAttribute="form" method="post">
    <fieldset>
        <legend>SUPER FIELD</legend>
        <p>
            SUPER ID:<form:input path="superId" />
        </p>
    </fieldset>
    <fieldset>
        <legend>SUB A FIELD</legend>
        <p>
            SUB A ID:<form:input path="subAId" />
        </p>
    </fieldset>
    <p>
        <input type="submit" value="register" />
    </p>
</form:form>
19
zono

POSTリクエストを処理するとき、Springは次のことを行います。

  • _@SessionAttributes_なし:SpringはSuperFormの新しいインスタンスをインスタンス化し(タイプはregister()の署名から推測されます)、フォームフィールドからの値によってそのプロパティを設定し、それをに渡します。 register()メソッド。

  • _@SessionAttributes_の場合:Springはセッションからモデル属性のインスタンスを取得し(_@SessionAttributes_が存在するためにGETを処理するときに配置された場所)、fromフィールドの値によってプロパティを更新します。そしてそれをregister()メソッドに渡します。

つまり、_@SessionAttributes_を使用すると、register()は、getCreateForm()によってモデルに配置されたモデル属性オブジェクトの同じインスタンスを取得します。

24
axtavt

@axtavtの発言に加えて、getCreateFormにドロップダウン(リストまたはマップ)の値を入力するか、registerメソッドに必要な形式で値を入力するとします。それらをフォームで表示したくない(非表示のフィールドでも表示しない)。ここで、registerメソッドでエラーが発生し、フォームを再度表示する必要があるとします。ドロップダウン値や次の投稿で必要になるその他の値を入力するには、フォームに再入力する必要があります。 @SessionAttributeは、@ axtavtが上で非常によく説明されているので、ここで役立ちます。

3
Ritesh

Springリファレンスドキュメントによると、@ModelAttributeアノテーション付きメソッド引数は次のように解決されます。

  • モデルオブジェクトが存在する場合はそれから取得します(通常は@ModelAttributeアノテーション付きメソッドを介して追加されます)
  • @SessionAttributesを使用してHTTPセッションから取得します。
  • コンバーターを介して@ModelAttribute名と一致するURIパス変数を使用して作成します
  • デフォルトのコンストラクターを使用して作成し、それをModelに追加します。

ハンドラークラスには、引数として名前のリストを使用して@SessionAttributesで注釈を付けることができます。これは、@SessionAttributesアノテーションで指定された名前と一致するモデルデータに存在するデータ項目を(セッションで)永続化するようにSpringに指示するためです。

したがって、SampleControllerでは、postメソッドの@ModelAttribute引数は、上記の解決方法により、@SessionAttributesフィールドで解決されます。

0
S R Chaitanya
@Controller
@SessionAttributes("test")
public class Controller{
    Customer customer;

    public Controller() {
        super();
        customer = new Customer();
    }

    @ModelAttribute("test")
    public Customer getCustomer() {
       customer.setName("Savac");
       return customer;
    }

    @RequestMapping({"/index"})
    public ModelAndView showMainPage (@ModelAttribute("test") Customer customer, ModelMap model, method = RequestMethod.GET) {
        //in the view you set the name
        return new ModelAndView("index");
    }

    @RequestMapping(value = "customer/{customerID}", method = RequestMethod.GET)
    public ModelAndView viewAdvice(@PathVariable("customerID") int customerID, @ModelAttribute("test") Customer customer, ModelMap model) {
        customer.setName("AnotherName");
        model.addAttribute("test", customer);
        return new ModelAndView("customer");
    }

}
0
user1275645