概述
SpringMVC中@ModelAttribute是一个重要的属性,理解好它是用好自动封装等功能的基础。可是@ModelAttribute和@RequestMapping组合后的状况较多,很容易让人糊涂。
1、如果想向Model中绑定对象属性:
例:一个没有使用@ModelAttribute注解的Controller方法:
@RequestMapping("/hello")
public String hello(User user) {
user.setId(520);
user.setName("U love me");
return "hello";
}
- 其中User包含id和name两个私有属性,含有公共setter和getter方法,执行此方法时会将key为"user",value为User user的对象加入到Model,在hello.jsp页面通过
${user.id}
和${user.name}
获取值。 - 注意:这里即便参数名称是user1,key同样仍是"user"。
@RequestMapping("/hello")
public String hello(Model model,int id,String username) {
User user=new User();
//这里是经过反射从request里面拿值再set到user
user.setId(id);
user.setName(username);
model.addAttribute("user",user);
return "hello";
}
- 也可以通过model.addAttribute()显示的绑定数据,在hello.jsp页面通过
${user.id}
和${user.name}
获取值,与上面效果相同,好处是可以指定key的值。
2、使用@ModelAttribute向Model中绑定属性:
@ModelAttribute的基本用法:
- @ModelAttribute最主要的作用是将数据添加到Model对象中,用于视图页面展示时使用;
- @ModelAttribute等价于
model.addAttribute("attributeName", value);
但是根据@ModelAttribute注解的位置不同,和其他注解组合使用,致使含义有所不同;- 在同一个Controller中,标注了@ModelAttribute的方法实际上会在@RequestMapping方法之前被调用,因此对于一个controller映射多个URL的用法来说,要谨慎使用;
- 一个Controller可以拥有多个@ModelAttribute方法,同一个Controller内的这些方法都会在@RequestMapping方法之前被调用;
- @ModelAttribute标注的方法也可以定义在@ControllerAdvice标注的类中,并且这些@ModelAttribute可以同时对多个控制器生效。
@ModelAttribute注解可被标注在方法或方法参数上:
- @ModelAttribute标注在方法上时,说明该方法是用于添加一个或多个属性到model上;这样的方法能接收与@RequestMapping注解相同的参数类型,只不过不能直接被映射到具体的请求上;
- @ModelAttribute标注在方法参数上时,说明该方法参数的值将由model中取得;如果model中找不到,那么该参数会先被实例化,然后被添加到model中;在model中存在以后,请求中所有名称匹配的参数都会填充到该参数中;
- 这在Spring MVC中被称为数据绑定,一个非常有用的特性,我们不用每次都手动从表格数据中转换这些字段数据;
- @ModelAttribute注解的scope为request,要想跨请求进行数据共享使用@SessionAttributes()注解。
3、使用@ModelAttribute注解标注在方法上时:
3.1)@ModelAttribute标注void返回值的方法:
@Controller
public class DemoController {
@ModelAttribute
public void addUser(Model model, User user){
model.addAttribute("user", user);
}
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
- 上面例子中,当发起
/hello
请求后,addUser方法在hello方法之前被调用,它把请求参数User user加入到一个key为"user",value为User user对象的Model属性中,在它执行后,hello方法被调用,返回的视图名hello和model已由@ModelAttribute标注的方法生产好了,此时在hello.jsp页面就可以从Model中获取user相关的数据了; - 当@ModelAttribute注解标注返回值为void的方法时,需要传入Model参数,并使用
model.addAttribute()
方法手动的往Model上绑定数据。
3.2)@ModelAttribute标注返回具体类的方法:
@Controller
public class DemoController {
@ModelAttribute
public User addUser(User user) {
return user;
}
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
- 执行addUser的过程中,会添加一个key为user的对象到model(这里model属性的名称没有指定,它由返回类型隐含表示,如该方法返回User类型,那么这个model属性的key是user)。
3.3)@ModelAttribute(value="")标注返回具体类的方法:
@Controller
public class DemoController {
@ModelAttribute("user1")
public String addUser(User user) {
return user;
}
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
- 使用@ModelAttribute注解的value属性,来指定model属性的名称;
- 在执行addUser过程中,会添加两个对象到model中,一个是key为user的对象(由addUser方法的User user引发的),另一个是key为user1的对象(由注解
@ModelAttribute("user1")
引发的) - 通过上面的例子,我们再jsp页面中通过key为user和user1都可以获取到User user对象的数据,为什么会这样呢?接着看下面的例子;
3.3.1)进一步测试:
还是将@ModelAttribute注解标注到返回值为User的方法上,
而此时,我们接收到User user以后不返回该对象,而是重新new User对象返回。
@Controller
public class DemoController {
@ModelAttribute("user1")
public User addUser(Model model, User user){
return new User(520, "U love me");
}
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
- 通过测试,在jsp页面通过key为user可以获取到参数中的User user对象,而通过key为user1可以获取到我们返回得new User(520, “U love me”);这个对象;
- 结论:不论我们使不适用@ModelAttribute注解value这个属性,都会通过传入的User user参数创建一个key为user值为User user的model属性,如果我们指定了value值,那么会通过@ModelAttrubute注解再创建一个key为value值得model属性进行绑定。
4、使用@ModelAttribute注解标注在方法参数上时:
4.1)从model中获取:
@Controller
public class DemoController {
@ModelAttribute("user1")
public User addUser() {
return new User(520, "U love me");
}
@RequestMapping(value = "/hello")
public String hello(@ModelAttribute("user1") User user) {
return "hello";
}
}
- 上面例子中,@ModelAttribute(“user1”) 标注方法参数,参数user的值来源于addUser()方法中的model属性,在jsp页面中可以通过user1获取到User(520, “U love me”);
- 此时如果该Controller类上没有标注@SessionAttributes(“user”)注解,那么scope为request,如果标注了,那么同时也将key为user的属性存入Session中,scope为session。
4.2)从Form表单或URL参数中获取(实际上,不做此注解也能拿到user对象):
@Controller
public class DemoController {
@ModelAttribute("user1")
public User addUser(){
return new User(520, "U love me");
}
@RequestMapping(value = "/hello")
public String hello(@ModelAttribute("user1") User user) {
return "hello";
}
}
- 在上面例子中,我们通过form提交了User(1, “18”)参数,而在@ModelAttribute注解标注的方法中我们在Model中绑定了user1的User(520, “U love me”),此时我们调用hello方法后,通过jsp页面访问user1得到的却是User(1, “18”),说明Model中之前绑定的key为user1的值在hello方法中被覆盖了;
- 注意:这时候这个User类一定要有无参的构造函数。
5、另类:@ModelAttribute和@RequestMapping同时注释一个方法:
@Controller
public class DemoController {
@RequestMapping(value = "/hello")
@ModelAttribute("attributeName")
public String hello() {
return "hi";
}
}
- 此时这个方法的返回值并不是表示一个视图名称,而是model属性的值,视图名称由RequestToViewNameTranslator根据请求"/hello",转换为逻辑视图hello;
- Model属性名称由@ModelAttribute(value=””)指定,相当于在request中封装了key=attributeName,value=hi。
最后
以上就是体贴戒指为你收集整理的SpringMVC中的@ModelAttribute注解【详解】的全部内容,希望文章能够帮你解决SpringMVC中的@ModelAttribute注解【详解】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复