在Spring MVC里,@ModelAttribute通常使用在Controller方法的参数注解中,用于解释model entity;但同时,也可以放在方法注解里。
如果把@ModelAttribute放在方法的注解上时,代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法。下面介绍@ModelAttribute常用的三种方式。
1、@ModelAttribute注释一个方法的参数:
1)从model中获取数据
@Controller
public class HelloWorldController {
@ModelAttribute("user")
public User addAccount() {
return new User("jz","123");
}
@RequestMapping(value = "/helloWorld")
public String helloWorld(@ModelAttribute("user") User user) {
user.setUserName("jizhou");
return "helloWorld";
}
}
在这个例子里,请求/helloWorld后执行helloWorld方法之前,会先执行addAccount方法。有因为,@ModelAttribute("user") User user注释方法参数,
所以参数user的值来源于addAccount()方法中的model属性。 此时如果方法体没有标注@SessionAttributes("user"),那么scope为request,如果标注了,那么scope为session。
2)从Form表单或URL参数中获取(实际上,不做此注释也能拿到user对象)
@Controller
public class HelloWorldController {
@RequestMapping(value = "/helloWorld")
public String helloWorld(@ModelAttribute User user) {
return "helloWorld";
}
}
2、 @ModelAttribute注释在方法上,当做方法拦截器使用:
如果把@ModelAttribute放在方法的注解上时,代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法。我们可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。比如权限验证。
@Controller
@RequestMapping(value="test")
public class PassportController {
@ModelAttribute
public void preRun() {
System.out.println("Test Pre-Run");
}
@RequestMapping(method=RequestMethod.GET)
public String index() {
return "login/index";
}
@RequestMapping(value="login", method=RequestMethod.POST)
public ModelAndView login(@ModelAttribute @Valid Account account, BindingResult result)
:
:
}
}
在调用所有方法之前,都会先执行preRun()方法。
3、@ModelAttribute放在方法上,做为Model输出到View时使用:
1)@ModelAttribute注释void返回值的方法
@Controller
public class HelloModelController {
@ModelAttribute
public void populateModel(@RequestParam String abc, Model model) {
model.addAttribute("attributeName", abc);
}
@RequestMapping(value = "/helloWorld")
public String helloWorld() {
return "helloWorld.jsp";
}
}
在这个代码中,访问控制器方法helloWorld时,会首先调用populateModel方法,将页面参数abc(/helloWorld.ht?abc=text)放到model的attributeName属性中,在视图中可以直接访问。
jsp中使用:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
</head>
<body>
<c:out value="${attributeName}"></c:out>
</body>
</html>
2)@ModelAttribute注释返回具体类的方法
@Controller
public class Hello2ModelController {
@ModelAttribute
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld() {
return "helloWorld.jsp";
}
}
当用户请求 http://localhost:8080/test/helloWorld2时,首先访问populateModel方法,返回User对象
,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称是user。
这个例子中model属性名称有返回对象类型隐含表示,model属性对象就是方法的返回值。它无须要特定的参数。
jsp中访问:
<c:out value="${user.account}"></c:out>
3)也可以指定属性名字:
@Controller
public class Hello2ModelController {
@ModelAttribute(value="myUser")
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld(Model map) {
return "helloWorld.jsp";
}
}
jsp中使用:
<c:out value="${myUser.account}"></c:out>
4)合并对象:
@Controller
public class Hello2ModelController {
@ModelAttribute
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld(User user) {
user.setName("老王");
return "helloWorld.jsp";
}
}
合并对象也可以指定名字:
@Controller
public class Hello2ModelController {
@ModelAttribute("myUser")
public User populateModel() {
User user=new User();
user.setAccount("ray");
return user;
}
@RequestMapping(value = "/helloWorld2")
public String helloWorld(@ModelAttribute("myUser") User user) {
user.setName("老王");
return "helloWorld.jsp";
}
}
在jsp中访问:
<c:out value="${myUser.name}"></c:out>
<c:out value="${myUser.account}"></c:out>
参考:
http://blog.csdn.net/hejingyuan6/article/details/49995987
http://www.cnblogs.com/HD/p/4127915.html