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方法的参数中。

相关文章:

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

相关文章推荐

C++ 打印蛇形矩阵

代码根据论坛的一个帖子修改而成。#include int row,col; int matrix[100][100]={0}; void UpFillNum(int); void Down...
  • bdmh
  • bdmh
  • 2010-12-29 14:48
  • 5835

Java Web基础知识之安全:人生苦短,注意安全

关于web程序中的安全方面,想必大多数人都不甚了解,或者说感觉没有必要了解,身边开发网站的人主要就是注重后台的功能和前台的界面,不要说程序的安全问题,甚至后台数据库访问的问题可能都没有下大力气解决。但...

spring学习之@SessionAttributes

一、@ModelAttribute    在默认情况下,ModelMap 中的属性作用域是 request 级别是,也就是说,当本次请求结束后,ModelMap 中的属性将销毁。如果希望在多个请...

Spring AOP学习笔记(1):AOP基础知识

一、使用AOP前的经验

卸载后怎么重新配置mysql服务

卸载后怎么重新配置mysql服务安装MYSQL不成功,一般是因为服务器可能安装过MYSQL而没有完全卸载。 如遇到MYSQL启动不了的下列情况:无论双击mysqld.exe还是使用命令行,都没反映...

Spring AOP学习笔记(2):AOP前置通知&后置通知

一、AOP前置通知

【caffe学习笔记之7】caffe-matlab/python训练LeNet模型并应用于mnist数据集(2)

【案例介绍】 LeNet网络模型是一个用来识别手写数字的最经典的卷积神经网络,是Yann LeCun在1998年设计并提出的,是早期卷积神经网络中最有代表性的实验系统之一,其论文是CNN领域第一篇经...

SpringMVC学习笔记(6):处理模型数据(1)

既然我们使用的框架叫SpringMVC,那么模型就必不可少,每当我们发送一个请求,后台服务器进行计算和处理之后会返回模型数据,我们要将这个模型数据返回给客户端,通过将这些数据嵌入到一个页面中传递给用户...

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

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

SpringMVC学习笔记(4):绑定数据(2)

之前一片已经写到了绑定基本类型的参数,包括字符串、数字还有http的请求头等,但是在实际开发中有很多这样的需求,前台向后台传递一个json对象,这样的参数如果是通过一个字符串来传递可想而知是多痛苦,所...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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