@PathVariable和@ModelAttribute的值重叠


问题内容

User在与的会话中存储了一个对象@SessionAttributes。还有一个简单的装饰方法,@ModelAttribute用于在会话的值为null时对其进行初始化。

用户类别:

@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的文档(请参阅下文)之后,我假设这是预期的行为:

下一步是数据绑定。WebDataBinder类将请求参数名称(包括查询字符串参数和表单字段)匹配,以按名称对属性字段进行建模。在必要时应用类型转换(从String到目标字段类型)后,将填充匹配字段。

但是,我认为这种情况相当普遍,其他人如何处理呢?如果我的发现是正确的,并且这是预期的行为(或错误),则似乎很容易出错。

可能的解决方案:

  1. 更改@PathVariable("id")@PathVariable("somethingElse")。可以,但是使用@RequestParam并不是那么简单(例如,我不知道如何将jqgrid的请求参数ID更改为其他名称,但这是另一个问题)。
  2. @PathVariable("id")类型从Long 更改为Int。这将使User.idid类型不同,但投龙长得难看:)
  3. 不要@ModelAttribute在这里使用并User再次查询数据库。与其他方法不一致,并且涉及冗余的数据库调用。

有什么建议么?


问题答案:

这种方法怎么样-

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