一、SpringMVC 输出模型数据概述
JavaWEB 中的响应数据常用的操作有:
(1)在域对象中存取数据 如:request.setAttribute(),request.getAttribute(),request.removeAttribute()
(2)请求转发:request.getRequestDispatcher("地址").forward(req,resp);
(3)重定向:response.sendRedirect();
SpringMVC 提供了几种途径输出模型数据:
Map、Model 和 ModelMap:入参为 org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
ModelAndView:处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据;
@SessionAttributes:将模型中的某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性
@ModelAttribute:方法入参标注该注解后, 入参的对象就会放到数据模型中
二、处理模型数据之 Map,Model,ModelMap
1、Spring MVC 在内部使用了一个 org.springframwork.ui.Model 接口存储模型数据;
2、Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器;
3、如果方法的形参为 Map、ModelMap 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这个形参;
4、在方法体内,开发者可以通过这个形参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据;
可以在方法处传入 Map、或者 Model 或者 ModelMap,给这些参数里面保存的所有数据都会放在【请求】域中,可以在页面获取;
示例代码:
@RequestMapping(value = "/handle01")
public String handle01(Map<String, Object> map) {
System.out.println("map类型:" + map.getClass());
map.put("msg", "你好");
map.put("haha", "haha");
return "success";
}
/**
* Model:一个接口
* @param model
* @return
*/
@RequestMapping(value = "/handle02")
public String handle02(Model model) {
System.out.println("model类型:" + model.getClass());
model.addAttribute("msg", "你好坏!");
return "success";
}
@RequestMapping(value = "/handle03")
public String handle03(ModelMap modelMap) {
System.out.println("modelMap类型:" + modelMap.getClass());
modelMap.addAttribute("msg", "你好棒!");
modelMap.addAttribute("haha", 18);
return "success";
}
Map、Model、ModelMap 和 BindingAwareModelMap 之间的关系:
-
Map、Model、ModelMap 最终都是 BindAwareModelMap 在工作,
-
相当于给 BindAwareModelMap 中保存的东西都会被放在请求域中;
-
org.springframework.validation.support.BindingAwareModelMap
推荐使用 Map,便于框架移植
三、处理模型数据之 ModelAndView
方法的返回值可以变成 ModelAndView 类型:即包含视图信息(页面地址)也包含模型数据(给页面带的数据),而且数据是放在请求域中;
添加模型数据:
MoelAndView addObject(String attributeName, Object attributeValue)
ModelAndView addAllObject(Map<String, ?> modelMap)
设置视图:
void setView(View view) 设置视图对象
void setViewName(String viewName) 设置视图名字
获取模型数据:
protected Map<String, Object> getModelInternal() 获取模型数据
public ModelMap getModelMap()
public Map<String, Object> getModel()
示例:
//返回值是ModelAndView,可以为页面携带数据
@RequestMapping("/handle04")
public ModelAndView handle04(){
//之前的返回值我们就叫视图名;视图名视图解析器是会帮我们最终拼串得到页面真实地址
//ModelAndView mv = new ModelAndView("success0");
ModelAndView mv = new ModelAndView();
mv.setViewName("success0");
mv.addObject("msg","嗨起来");
return mv;
}
三种方式实现作用域放值
- 使用 ModelAndView
- 使用 Map
- 使用 Model 或 ModelMap
不管使用以上哪种方式,最后都会把 Model 数据和 View 数据封装成 ModelAndView 对象中。
四、处理模型数据之 SessionAttributes 注解
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes
, Spring MVC 将在模型中对应的属性暂存到 HttpSession
中。
@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中;
如果满足类型或者 value 值,给 BindingAwareModelMap 中保存的数据或者 ModelAndView 中 的数据,则会在 session 域中也存放一份设置的键值对;
可以通过 value 指定保存数据时要给 session 中放的数据的 key
使用:
value = {"msg", "haha"}:只要保存的是这种 key 的数据,给 session 中放一份
types = {String.class}:只要保存的是这种类型的数据,给 session 中也放一份
示例:
① @SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。
② @SessionAttributes(value={“user1”, “user2”})
③ @SessionAttributes(types={User.class, Dept.class})
④ @SessionAttributes(value={“user1”, “user2”}, types={Dept.class})
控制器:
@Controller
//@SessionAttributes("user")
@SessionAttributes(value={"user"},types={String.class})
public class SpringMVCController {
/**
* @SessionAttributes
* 除了可以通过属性名指定需要放到会话中的属性外(实际上是通过value指定key值),
* 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上是通过types指定类型)
* 注意:只能放在类的上面,不能修饰方法
*/
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map<String,Object> map){
User user = new User("Tom","123","tom@atguigu.com",22);
map.put("user", user);
map.put("school", "atguigu");
//默认是被存放到request 域,如果设置了@SessionAttribute注解,就同时存放到session域中
return "success";
}
}
注意:不推荐使用 @SessionAttributes
,可能会引发异常(不可控),如果要给 session 域中存放数据,推荐使用原生 API。