2012-07-23 50 views
9

我有一個User對象存儲在與@SessionAttributes的會話中。一個簡單的方法用@ModelAttribute修飾,以便在會話的值爲空時對其進行初始化。@PathVariable和@ModelAttribute重疊的值

用戶等級:

@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類將請求參數名稱(包括查詢字符串參數和表單字段)與名稱建模屬性字段相匹配。在必要時應用類型轉換(從字符串到目標字段類型)後匹配字段已填充。

但是,我認爲這種情況相當普遍,其他人怎麼處理呢?如果我的發現是正確的,並且這是預期的行爲(或錯誤),這似乎是非常容易出錯的。

可能的解決方案:

  1. 變化@PathVariable("id")@PathVariable("somethingElse")。工作,但它不像@RequestParam一樣簡單(例如,我不知道如何將jqgrid的請求參數id更改爲別的東西,但這是另一個問題)。
  2. @PathVariable("id")類型從Long更改爲Int。這將使User.idid類型不同,但投給龍看起來很難看:)
  3. 請不要在這裏使用@ModelAttribute並再次查詢User的DB。與其他方法不一致並涉及冗餘的數據庫調用。

有什麼建議嗎?

+0

一個黑客第四選項,如果你更改順序 - '@ ModelAttribute'先'@ PathVariable' 。 – 2012-07-23 20:07:56

+0

結果是一樣的,但它是值得的嘗試。 – Ulises 2012-07-23 22:23:47

+0

是的,後來實際上意識到User的匹配屬性將與uri變量匹配。你的方法看起來不錯,我又增加了一個答案。 – 2012-07-24 00:18:28

回答

5

如何對這種做法 -

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

不錯。這是一個小小的變化,它的工作原理。快速的問題,我沒有看到'模型'getAttribute()',我應該只是'(用戶)uiModel.asMap()。get(「user」)'? – Ulises 2012-07-24 01:26:13

+0

是的,我的錯!讓我編輯答案來改變這一點。 – 2012-07-24 01:35:03

+0

+1我喜歡你的答案,但是我會標記它,但我想看看我是否聽到更多。非常感謝您的幫助。 – Ulises 2012-07-24 01:36:01

0

使用@SessionAttribute

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