我有一個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類將請求參數名稱(包括查詢字符串參數和表單字段)與名稱建模屬性字段相匹配。在必要時應用類型轉換(從字符串到目標字段類型)後匹配字段已填充。
但是,我認爲這種情況相當普遍,其他人怎麼處理呢?如果我的發現是正確的,並且這是預期的行爲(或錯誤),這似乎是非常容易出錯的。
可能的解決方案:
- 變化
@PathVariable("id")
到@PathVariable("somethingElse")
。工作,但它不像@RequestParam一樣簡單(例如,我不知道如何將jqgrid的請求參數id更改爲別的東西,但這是另一個問題)。 - 將
@PathVariable("id")
類型從Long更改爲Int。這將使User.id
和id
類型不同,但投給龍看起來很難看:) - 請不要在這裏使用
@ModelAttribute
並再次查詢User
的DB。與其他方法不一致並涉及冗餘的數據庫調用。
有什麼建議嗎?
一個黑客第四選項,如果你更改順序 - '@ ModelAttribute'先'@ PathVariable' 。 – 2012-07-23 20:07:56
結果是一樣的,但它是值得的嘗試。 – Ulises 2012-07-23 22:23:47
是的,後來實際上意識到User的匹配屬性將與uri變量匹配。你的方法看起來不錯,我又增加了一個答案。 – 2012-07-24 00:18:28