2012-07-23 12 views
9

Userオブジェクトは、セッションに@SessionAttributesという名前で格納されています。そして、セッションの値がnullのときはいつでも初期化するために、@ModelAttributeで装飾された単純なメソッドです。@PathVariableと@ModelAttributeの値が重複しています

Userクラス:

@Entity 
@Table(name="USER") 
public class User implements java.io.Serializable { 

    private Long id; 
    private String username; 
    private String password; 
    .... 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name ="ID") 
    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
    ... 

コントローラー:

@RequestMapping("/item") 
@Controller 
@SessionAttributes({"user"}) 
public class MyController { 

@ModelAttribute方法:

@ModelAttribute("user") 
    public User createUser(Principal principal) { 
     return userService.findByUsername(principal.getName()); 
    } 

すべて、この特定の方法以外で期待通りに動作するようです:

@RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    public String showItem(@PathVariable("id") Long id, @ModelAttribute("user") User user, 
      Model uiModel) { 
    ...  
} 

User.id@PathVariable("id")に設定されています。私は@RequestParamでもこれに遭遇したと信じています。私は、両方が同じ名前とタイプを持っているからです。 Spring's documentation(下記参照)を読んだ後、これは予想される動作であると仮定しています。

次のステップはデータバインディングです。 WebDataBinderクラスは、クエリー文字列パラメータやフォームフィールドを含むリクエストパラメータ名と名前でモデル属性フィールドを照合します。一致するフィールドは、必要に応じて型変換(Stringから対象フィールド型への変換)が行われた後に設定されます。

しかし、このシナリオはかなり一般的だと思いますが、他の人はどのようにこれを処理していますか?私の発見が正しいと思われ、これが予想される動作(またはバグ)である場合、これは非常にエラーが発生する可能性が高いです。

考えられる解決策:

  1. 変更@PathVariable("somethingElse")@PathVariable("id")。動作しますが@RequestParamではそれほど簡単ではありません(たとえば、jqgridのリクエストパラメータidを他のものに変更する方法はわかりませんが、これは別の問題です)。
  2. @PathVariable("id")タイプをLongからIntに変更します。これにより、User.ididのタイプは異なりますが、ロングへのキャストは醜いものになります:)
  3. ここでは@ModelAttributeを使用せず、UserのDBに再度クエリしてください。他のメソッドと一貫性がなく、冗長なDBコールが必要です。

+0

Aがハック第四オプション、あなたが順序を変更した場合 - '@ ModelAttribute'最初にして' @ PathVariable' 。 –

+0

結果は同じでしたが、試してみる価値がありました。 – Ulises

+0

はい、実際には、Userの一致するプロパティがuri変数から照合されることが後で分かります。あなたのアプローチはよく見える、私は答えとして1つを追加しました。 –

答えて

5

どのようにこのアプローチについて -

@RequestMapping(value = "/{id}", method = RequestMethod.GET) 
public String showItem(@PathVariable("id") Long id, 
      Model uiModel) { 
     User user = (User)uiModel.asMap().get("user"); 
    ...  
} 
+0

悪くない。それは小さな変化であり、動作します。私はちょうど '(User)uiModel.asMap()。get(" user ")'を 'Model'に' getAttribute() 'を見ていませんでした。 – Ulises

+0

はい、私の間違いです!これを変更する答えを編集してみましょう。 –

+0

+1私はあなたの答えが好きですが、私はそれをマークする前に私はもっと聞くかどうかを見たいと思います。ご助力ありがとうございます。 – Ulises

0

使用@SessionAttribute

@RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    public String showItem(@PathVariable("id") Long id, @SessionAttribute("user") User user, 
      Model uiModel) { 
    ...  
} 
関連する問題