SpringMVC数据存储
1、Model
Model是一个接口,其实现类为ExtendedModelMap,继承了ModelMap类。
public class ExtendedModelMap extends ModelMap implements Model
它的addAttribute方法,会使用到ModelMap的addAttribute方法,ModelMap又会调用到继承自LinkedHashMap的put方法
public ExtendedModelMap addAttribute(String attributeName, @Nullable Object attributeValue) {
super.addAttribute(attributeName, attributeValue);
return this;
}
2、ModelMap
ModelMap是一个类,继承LinkedHashMap,因此为Map结构,可以使用Key/Value形式存储值。
- LinkedHashMap简单来说是一个有序的HashMap,其是HashMap的子类,HashMap是无序的。
public class ModelMap extends LinkedHashMap<String, Object>
ModelMap对象主要用于传递控制方法处理数据到结果页面,也就是说我们把结果页面上需要的数据放到ModelMap对象中即可,
他的作用类似于request对象的setAttribute方法的作用: 用来在一个请求过程中传递处理的数据。
它的addAttribute方法,底层调用的是Map的put方法
public ModelMap addAttribute(String attributeName, @Nullable Object attributeValue) {
Assert.notNull(attributeName, "Model attribute name must not be null");
this.put(attributeName, attributeValue);
return this;
}
3、ModelAndView
添加模型数据用addObject;
设置视图setViewName;
ModelAndView 对象有两个作用:
(1). 设置转向地址,这也是ModelAndView和ModelMap的主要区别.设置方式如下所示:
ModelAndView view = new ModelAndView("path:student");
或者通过setViewName方式:
public void setViewName(String viewName){...}
(2). 将控制器方法中处理的结构数据传递到jsp页面,把数据放到ModelAndView对象中其实底层是把数据放入到了ModelMap中
public ModelAndView addObject(String attributeName, Object attributeValue) {
this.getModelMap().addAttribute(attributeName, attributeValue);
return this;
}
public ModelMap getModelMap() {
if (this.model == null) {
this.model = new ModelMap();
}
4、Map
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map){
map.put("name","张三");
map.put("password","123456");
map.put("age",18);
return "success";
}
5、Request
使用request域对象存储数据:将请求中的参数存储在request中,使用setAttribute()方法
@RequestMapping("/testRequest")
public String testRequest(HttpServletRequest request) {
request.setAttribute("name", "张三");
return "success";
}
6、Session
将数据存储到session作用域中
@RequestMapping("/testSession")
public String testSession(HttpSession session) {
session.setAttribute("name", "张三");
return "success";
}
Model、ModelMap、ModelAndView、Map是SpringMVC中特有的,Request、Session是servlet的API,是通用的。
7、@SessionAttributes
SpringMVC提供了一种可以临时给Session域中保存数据的方式,那就是使用@SessionAttributes注解,但该注解只能标注在类上
使用@SessionAttributes(value = “msg”)注解会在给BindingAwareModelMap中保存数据的同时,为session中存放一份。value指定保存数据时要给session中存放的key。
- value = {“msg”}:只要保存的是这种key的数据,给session中存放一份。
- types={String.class}:只要保存的是这种类型的数据,给session中存放一份。
SpringMVC虽然提供了为session存放数据的@SessionAttributes注解,不过还是推荐使用原始API,因为使用SpringMVC提供的注解可能会引发异常。
SpringMVC Redirect 跳转后保存Model 中的数据
-
手动拼接url
return "redirect:list-user.shtml?param1="+value1+"¶m2="+value2;
这个方式比较麻烦而且有个弊端,就是参数是中文的时候很难处理
-
自己封装一个类
自己进行一些封装,包括中文的处理,转码解码等,好处是可以根据自己想要的自由实现,坏处是增加了工作量。在一些没有提供现成工具的框架中适合用此方法。
-
使用spring mvc提供的现成的工具类
spring mvc中,我们常用的是ModelMap,但是它还提供了一个RedirectAttributesModelMap类,该类实现了RedirectAttributes接口,提供一个闪存存储方案,使属性能够在重定向时依旧生存而不用嵌入到url
public class RedirectAttributesModelMap extends ModelMap implements RedirectAttributes public interface RedirectAttributes extends Model
@RequestMapping(value = "delete-user", method = RequestMethod.POST) public String deleteUser(Long[] userId, RedirectAttributesModelMap modelMap) { userService.deleteUser(userId); modelMap.addFlashAttribute("resultMsg", "删除成功"); return "redirect:list-user.shtml"; }
发现进行redirect跳转后,“删除成功”的消息仍旧为我们保持着。
其实最底层仍旧是两种跳转,只不过spring又进行了封装而已,原理是把属性放到session中,在跳到页面后又在session中马上移除对象,所以在刷新一下后这个值就会丢掉。