SpringMVC学习笔记(7):处理模型数据(2)

原创 2016年06月02日 00:00:26

上一篇已经说了三种处理模型数据的方法, 最后一种是使用@ModelAttribute注解,在一开始学习这个注解的时候感觉很懵,完全不知道它是怎么起作用的,后来自己实践了一下才搞懂,感觉这个注解真是信息量太大了!!

@ModelAttribute可以在方法上使用,也可以在方法中的参数中使用,关于在这两个不同的地方使用时是有很大的差别的:

  • 在方法上使用时, SpringMVC在调用所有的请求处理器(被@RequestMapping注解的方法)前会执行被这个注解标识的所有方法;
  • 在方法的参数上使用时

一、 方法上使用@ModelAttribute

使用在方法上的目的就是用来添加模型数据,由于被@ModelAttribute注解的方法要在所有被@RequestMapping注解的方法调用前调用,所以可以将该被该注解标识的方法看成是请求拦截器,在所有请求处理器之前执行,一个Controller类中可以有多个被@ModelAttribute注解的方法,由于作为拦截器,所以它接收的参数类型和被@RequestMapping注解的方法的参数类型相同,即亦可以使用像@RequestParam和@PathVariable等注解。另外,在方法上使用该注解时有两种方式:
  • 方法没有返回值:当没有返回值时,我们就需要向该注解标识的方法中传递一个Model或者Map类型的参数来作为存储模型数据的容器,其实这里的容器类型可以使用在上一篇中说到的Map的对应的子类型也是可以的,实例如下:
@ModelAttribute
public void getGlobalInfo(Model model) {
	model.addAttribute("area", "China");
}
也可以写成这样:
@ModelAttribute
public void getGlobalInfo(Map<String, Object> map) {
	map.put("area", "China");
}
这样该Controller类中所有的@RequestMapping注解标识方法的返回的视图中都可以通过EL表达式获取这个模型数据;
  • 方法有返回值:当有返回值时,模型数据是被存储到SpringMVC为我们创建的容器中,实例如下:
@ModelAttribute
public Person getPerson(){
	Person person = new Person();
	person.setName("lmy86263");
	person.setAge(24);
	return person;
}
Person是一个POJO类,如下:
public class Person implements Serializable{
	private static final long serialVersionUID = 2158697392661485138L;
	private String name;
	private Integer age;
<span style="white-space:pre">	</span>// setter getter
}
在这里就是将Person对象存储到SpringMVC为我们创建的隐式容器中,属性的名称是”person“,至于这个属性名是怎么来的?不过不加指定,默认的属性名是非限定类型名称的第一个字母小写后作为属性名,这里就是将Person首字母小写作为属性名。如果不想使用默认的则可以使用@ModelAttribute注解中的value属性来指定属性名,比如使用@ModelAttribute("p"),这是在前台页面只能使用${p.name}而不能使用${person.name}。
还有一个疑问,网上一直没人写过,我在这里试一下,上面可以看到返回的诗句都是POJO类型,如果要是普通类型的数据是什么样的?尤其是普通类型使用默认参数名时是怎么样的?真的是String类型参数,属性名就是"string"?如下:
	@ModelAttribute
	public Integer getString(){
//		String msg = "string type";
//		return msg;
		Integer number = 12345;
		return number;
	}
经过测试,果然是这样,即使是String或者其基本类型的包装类也是安装上述所说的方式进行命名的,这里要注意的是不要使用基本类型,比如int,double等当返回值,这会导致抛出javax.el.ELException: The identifier [int] is not a valid Java identifier as required by section 1.19 of the EL specification这种异常,是EL表达式不能解析这种类型。

@ModelAttribute还可以应用到多个Controller类中,通过建立一个被@ControllerAdvice注解(这个注解很有用,在进行异常处理时还会用到这个注解)的类,在该类中建立一个被@ModelAttribute的方法,这时在该方法中填入的模型数据可以在多个被声明的Controller类中使用,如果@ControllerAdvice没有指定特定的Controller,那么该方法会应用到所有的Controller中,可以看下面的链接。
更进一步,@ModelAttribute注解还可以使用在@RequestMapping注解标识的方法中,这个时候该请求处理器的返回值就不是一个视图名,而是被认为是一个模型数据。但是我觉得这样使用不太好,所以尽量不要这样使用。

二、 参数上使用@ModelAttribute

在方法参数上使用@ModelAttribute是为了从模型中获取数据来传递到该参数上。如果模型中没有该对应的属性名,那么该类型的参数首先会实例化然后在加入到模型中,关于该类型的实例来自哪里是一个比较复杂的问题,如果有兴趣可以参考SpringMVC的文档。;如果发现有对应的属性名,那么参数的字段就会被该模型值填充,就是所谓的数据绑定。其实在从模型中取数据之前,将该注解使用在@RequestMapping方法参数上可以获取表单或者json数据,当表单或者ajax传递过来值时首先获取这部分的值,如果对应的对象的字段不存在才会去模型中查找对应的数据,好乱啊,看下面的实例:
有一个@ModelAttribute方法如下:
@ModelAttribute
public User getPerson(){
	User user = new User();
	user.setName("lmy");
	user.setAge(20);
	Address address = new Address();
	address.setCity("ts");
	address.setProvince("hb");
	user.setAddress(address);
	
	System.out.println("here user " + user);
	
	return user;
}
此处的User和上一篇中的User相同不再指出。
@RequestMapping方法如下:
@RequestMapping("/testModelAttributeParam")
public String testModelAttributeParam(@ModelAttribute("user") User user){
	System.out.println(user);
	return "view";
}
前台页面如下,没有传递city:
<html>
	<body>
		<form action="testModelAttributeParam" method="post">
			<input type="text" name="name">name</input>
			<input type="text" name="age">age</input>
			<input type="text" name="address.province">province</input>
			<!-- <input type="text" name="address.city">city</input> -->
			<input type="submit" value="submit" />
		</form>
	</body>
</html>
后台显示结果如下:
可以看出只有在前台没有传递city数据时,才会到模型中查找对应User中的city数据填充到@RequestMapping方法的参数中。

相关文章:

版权声明:本文为博主原创文章,未经博主允许不得转载。

SpringMVC 学习笔记(四) 处理模型数据

Spring MVC 提供了以下几种途径输出模型数据: – ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据 – Map及Model:入...
  • a67474506
  • a67474506
  • 2015年06月04日 15:49
  • 4705

SpringMVC-4 处理模型数据

  • 2017年03月25日 13:05
  • 3.79MB
  • 下载

SpringMVC中如何处理模型数据

Spring MVC 提供了以下几种途径输出模型数据: ModelAndView: 处理方法返回值类型为ModelAndView时, 方法体即可通过该对象添加模型数据 Map 及Model: 入参为o...
  • xiangwanpeng
  • xiangwanpeng
  • 2016年11月06日 22:13
  • 902

SpringMVC-处理模型数据

Spring MVC 提供了以下几种途径输出模型数据: 代码示例中配置web.xml中DispatcherServlet以及Servlet对应的-servlet.xml省略。 1.ModelAndVi...
  • sunyonggao
  • sunyonggao
  • 2016年06月01日 22:19
  • 952

SpringMVC处理模型数据(2)

上一篇文章中我们介绍了比较简单,也比较容易理解的处理模型数据的方法;现在我们进入下一个知识点,也是比较复杂的知识点,处理模型数据方法之ModelAttribute注解,我们在这里也就是谈谈对代码使用上...
  • AZHELL
  • AZHELL
  • 2017年05月08日 18:34
  • 95

SpringMVC学习(7):处理模型数据

SpringMVC提供了1.ModelAndView作为返回值添加模型数据2.Map作为传入参数,在处理方法返回时将Map中的数据添加到模型中 一、ModelAndView ModelAndVie...
  • qq_24627733
  • qq_24627733
  • 2017年04月23日 00:51
  • 81

springmvc 处理模型数据

处理模型数据 ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。 @ModelAttribute:方法入参标注了该注解后,入参对象...
  • u014695188
  • u014695188
  • 2016年04月29日 16:56
  • 169

SpringMVC处理模型数据

SpringMVC处理模型数据解析
  • u010834071
  • u010834071
  • 2014年12月04日 20:10
  • 1036

springmvc之处理模型数据

1.springmvc为什么要处理模型数据 当我们采用映射路径映射到方法处理完数据时,需要将数据显示在页面上。然而springmvc框架提供可以将模型数据暴露给视图的解决方案。 2.springmvc...
  • ya_1249463314
  • ya_1249463314
  • 2017年07月31日 10:08
  • 101

springmvc 处理模型数据

springmvc中,模型数据是非常重要的,因为视图的渲染,需要模型数据,而模型数据的生成则在我们定义的controller中。springmvc通过多种途经把模型数据暴露出来 ModelAndVie...
  • yingxiake
  • yingxiake
  • 2016年04月12日 08:20
  • 669
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SpringMVC学习笔记(7):处理模型数据(2)
举报原因:
原因补充:

(最多只允许输入30个字)