我是靠谱客的博主 体贴戒指,最近开发中收集的这篇文章主要介绍SpringMVC中的@ModelAttribute注解【详解】,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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注解【详解】所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部