您的位置:首页 > 编程语言 > Java开发

SpringMVC处理模型数据

2017-10-08 16:45 344 查看
• Spring MVC提供了以下几种途径输出模型数据:
§ ModelAndView:
□ 处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。
§ Map及 Model:
□ 入参为 org.springframework.ui.Model、org.springframework.ui.ModelMap或java.uti.Map时,处理方法返回时,Map中的数据会自动添加到模型中。
§ @SessionAttributes:
□ 将模型中某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性。
§ @ModelAttribute:
□ 方法中入参标注该注解后,入参的对象就会放到数据模型中。

1. ModelAndView:
a. 目标方法的返回值可以是ModelAndView类型,其中包含视图和模型信息。
b. SpringMVC会把ModelAndView的model中数据放入到 request域对象中。(从域对象中取出的方式为${requestScope.time}.)

c. 
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
String viewName = SUCCESS;
ModelAndView modelAndView = new ModelAndView(viewName);
// 添加模型数据到 ModelAndView 中.
modelAndView.addObject("time", new Date());
return modelAndView;
}
2. Model:
a. 目标方法可以添加map类型的参数
/**
*目标方法的入参可以是map类型
*@parammap
*@return

*/
@RequestMapping("/testMap")
publicStringtestMap(Map<String,Object>map){
System.out.println(map.getClass().getName());
map.put("names",Arrays.asList("Tom","Jerry","Mike"));
returnSUCCESS;
}
b. Arrays.asList()将一个数组转化成一个List对象,这个方法会返回一个ArrayList类型的对象,这个ArrayList类并非java.util.ArrayList类,而是Arrays类静态内部类!
3. SessionAttributes注解
a. 该注解可以设定将属性值设置如 Session域中(实际上使用的是value属性值)
b. 还可以通过模型属性的对象类型指定哪些模型属性需要放在会话中(实际上使用的是types属性值)。
注意:该注解只能放在类上面,而不能修饰方法。
@SessionAttributes(value={"user"},types={String.class})
@RequestMapping("/springmvc")
@Controller
publicclassSpringMVCTest{

privatestaticfinalStringSUCCESS="success";

@RequestMapping("/testSessionAttributes")
publicStringtestSessionAttributes(Map<String,Object>map){
Useruser=newUser("Tom","123456","a@163.com",15);
map.put("user",user);
map.put("school","atguigu");
returnSUCCESS;
}
4. @ModelAttribute注解
a. 在方法定义上使用#ModelAttribute注解:SpringMVC在调用目标处理方法之前,会先逐个调用在方法级上标注了@ModelAttribute 的方法。
b. 在方法的入参前使用 @ModelAttribute 注解:
i. 可以从隐含对象中获取隐含模型数据中获取对象,再讲请求参数绑定到对象中,在传入入参。
ii. 将方法入参对象添加到模型中。
iii. 有@ModelAttribute 标记的方法,会子啊每个目标方法执行之前被SpringMVC调用!
iv. @ModelAttribute 注解也可以来修饰目标方法POJO类型的入参,其value属性值有如下作用
1) SpringMVC 会使用 value 属性值在 implicitModel 中查找对应的对象,若存在则会直接传入到目标方法对应的入参中。
2) SpringMVC 会 value 为 key POJO 类型的对象为 value, 存入到 request中.
c. 例子:
@ModelAttribute
public void getUser(@RequestParams(value="id",required=false) Integer id, Map<String, Object> map){
System.out.println("modelAttribute method");
if(id != null){
//模拟从数据库中获取对象
User user = new User(1,"Tom","123456","tom@atguigu.com",12);
System.out.println("从数据库中获取一个对象:" +user);
//将新的 user 对象放入model中
map.put("user", user);
}
}

@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("修改: "+user);
return SUCCESS;
}

d. 运行流程:
i. 执行@ModelAttribute 注解修饰的方法:从数据库中取出对象,把对象放入到 Map 中。键为:user。
ii. SpringMVC 从 Map 中取出 User对象,并把表单请求参数赋值给 User 对象的对应属性。
iii. SpringMVC 把上述对象传入目标方法的参数。
iv. 注意:在 @ModelAttribute 修饰的方法张,放入到 Map 时的键需要和目标方法的入参类型的第一个字母小写的字符串一致!
i. 源代码分析的流程
1) 调用@ModelAttribute注解修饰的方法.实际上把@ModelAttribute方法中的Map 中的数据放在了 implicitModel中.
2) 解析请求处理器的目标参数,实际上该目标参数来自于WebDataBinder 对象的 target 属性.
a) 创建WebDataBinder对象:
One. 确定ObjectName 属性.若传入的 attrName 属性为 “”,则objectName为类名的第一个字母小写,注意:attrName.若目标方法的 POJO 属性使用了@ModelAttribute 来修饰,则attrName 值即为ModelAttribute的属性值。
Two. 确定 target 属性.
1. 在implicitModel 中查找 attrName 对应的属性值。若存在,ok
2. 若不存在:则验证当前Handler 是否使用了 @SessionAttributes 进行修饰,若使用了,则尝试从 Session 中获取 attrName 所对应的属性值。若 session 中没有对应的属性值,则抛出了异常。
3. 若 Handler 没有使用 @SessionAttributes 进行修饰,或@SessionAttributes 中没有使用 value 值指定的键和 attrName 相互匹配,则通过反射创建了 POJO 对象
b) SpringMVC 把表单的请求参数赋值给了 WebDataBinder 和target 对应的属性。
c) *SpringMVC 会把 WebDataBinder 的 attrName 和 target 传递到 implicitModel,进而传到 request 域对象中。
d) 把 WebDataBinder 的 target 作为参数传递给入参。(注:implicit 为隐含的意思) 
5. 小结:
i. SpringMVC 确定目标方法 POJO 类型入参的类型
i. 确定一个key:
1) 若目标方法 POJO 类型的参数没有使用 @ModelAttribute 作为修饰,则 Key 为POJO 类名第一个字母的小写。
2) 若使用了 @ModelAttribute 来修饰,则key为@ModelAttribute 注解 value属性值.
ii. 在ImplicitModel 中查找与 key 对应的对象,若存在,则作为入参传入
1) 若在@ModelAttribute 标记的方法中在 Map 中保存过,且 key 和 1 确定的 key 保持一致,则会获取到。
iii. 若 implicitModel 中不存在 key 对应的对象,则检查当前的 Handler 是否使用 @SessionAttributes 若使用了该注解,且@SessionAttributes 注解的 value 属性值中包含了 key,则会从 HttpSession 中获取 key 所对应的 value 值,若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常.
iv. 若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 直接的value 值中不含key,则会通过反射来创建 POJO 类型的参数,传入为目标方法的参数。
v. SpringMVC 会把 key 和POJO 类型的对象保存到 implicitModel 中,进而会保存到 request 中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: