运用SpringMVC框架时,在进行修改/更新操作的时候经常会用到@ModelAttribute注解;
Product对应的实体类:
public class Product {
private Integer id;
private String productName;
private Long productPrice;
public Product() {
super();
}
public Product(Integer id, String productName, Long productPrice) {
super();
this.id = id;
this.productName = productName;
this.productPrice = productPrice;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Long getProductPrice() {
return productPrice;
}
public void setProductPrice(Long productPrice) {
this.productPrice = productPrice;
}
@Override
public String toString() {
return "Product [id=" + id + ", productName=" + productName
+ ", productPrice=" + productPrice + "]";
}
}
发出请求的视图:
<form action="product/update">
id : <input type="text" name="id">
productName: <input type="text" name="productName"/>
<!-- productPrice: <input type="text" name="productPrice"/> -->
<input type="submit" value="test product update" />
</form>
如下是在控制器层 Controller 使用 注解@ModelAttribute
@ModelAttribute
//@ModelAttribute 能进行对表单数据的预处理
public void getProduct(@RequestParam(value="id",required=false) Integer id, Map<String, Object> map){
System.out.println("进入到getProduct!!!中...");
if(id != null){
//从数据库中获取对应的Product 对象
Product product = new Product(id,"Phone",5000L);
System.out.println("已经从数据库中获取出对应id的product对象:" + product);
map.put("product1", product);
}
else{
//无视
}
}
@RequestMapping("/update")
//POJO对象自动绑定
//此处方法中使用@ModelAttribute("product") 与 对象 Product product
public String update(Product product){
//此时本来是 Controller——ProductController 中的 update 发出一个
//productService.update(product);
System.out.println("product : " + product);
return SUCCESS; //SUCCESS存储这一个视图的字符串,使用Static变量有利于内存优化
}
当用户向服务器提交请求转发到 如上的Controller层时,无论执行当前Controller层中的任何中方法都会先运行以上的@ModelAttribute注解的方法,而此时getProduct没有放回转发任何数据,当 “ map.put("product1",product)” , 已经默认向HttpServletRequset90传递数据了,此时在之后返回响应给 SUCCESS视图之后 可在Request请求域中获取参数“”product1“; 同时也能获取参数”product“;
但是,问题来了,当使用@ModelAttribute("product1") 为 update(Product product)自动赋值时,也即如下代码:
@RequestMapping("/update")
//POJO对象自动绑定
//此处方法中使用@ModelAttribute("product") 与 对象 Product product
public String update(@ModelAttribute("product1") Product product){
//此时本来是 Controller——ProductController 中的 update 发出一个请求
//productService.update(product);
System.out.println("product : " + product);
return SUCCESS; //SUCCESS存储这一个视图的字符串,使用Static变量有利于内存优化
}
此时,在向SUCCESS视图中的Request请求域获取数据时,只能获取到参数为”product1“,而参数”product“此时却获取不到,也就是说”product“被”product1“覆盖了;
另一种情况,当在含有注解@ModelAttribute的方法中使得返回视图的参数和当前调用的方法中的参数一致时,则在SUCCESS视图中的请求域中将只会获取到参数”product“,且该参数中的属性,将是getProduct()方法中的product和update()方法中的product的合并,并且是以update()的属性为主;