域对象共享数据SpringMVC视图

域对象共享数据

session和model的区别_qq_42331499的博客-CSDN博客_model和session有什么不同

session的创建于销毁

session 创建和销毁时机_hotwater1015的博客-CSDN博客

当我们关闭浏览器,再打开它,连接服务器时,服务器端会分配一个新的session,也就是说会启动一个新的会话。那么原来的session是不是被销毁了呢?
通过实现一个SessionListener可以发现,当浏览器关闭时,原session并没有被销毁(destory方法没有执行),而是等到timeout到期,才销毁这个session。关闭浏览器只是在客户端的内存中清除了与原会话相关的cookie,再次打开浏览器进行连接时,浏览器无法发送cookie信息,所以服务器会认为是一个新的会话。因此,如果有某些与session关联的资源想在关闭浏览器时就进行清理(如临时文件等),那么应该发送特定的请求到服务器端,而不是等到session的自动清理。

session的作用域只与浏览器是否关闭有问题,当tomcat服务器关闭时,此时session会保存到磁盘中,当服务器再次开启的时候,session会活化到浏览器中,但是只要不关闭浏览器,session就不会改变。但是注意如果cookie已经销毁了,就找不到对应的session了,哪怕时间并没有超出。

使用ModelAndView向request域对象共享数据

ModelAndView拥有两个功能,一个是共享数据,另外一个设置视图名称

1
2
3
<body>
<a th:href="@{/target}">跳转</a>
</body>
1
2
3
4
5
6
7
8
9
@RequestMapping(value = "/target")
public ModelAndView toTarget(){
ModelAndView mav=new ModelAndView();
//存储数据
mav.addObject("test","test ModelAndView");
//设置视图
mav.setViewName("target");
return mav;
}
1
2
3
4
<table>
<tr><td th:text="${test}">
</td></tr>
</table>

使用Model传递域对象

1
2
3
4
5
@RequestMapping("/target")
public String target(Model model){
model.addAttribute("model","model");
return "target";
}

使用map共享域对象

1
2
3
4
5
@RequestMapping("/target")
public String target(Map<String ,Object> map){
map.put("map","hello map");
return "target";
}

使用ModelMap

1
2
3
4
5
@RequestMapping("/target")
public String target(ModelMap modelMap){
modelMap.addAttribute("modelmap","hello modelmap");
return "target";
}

总结

上述四种获取域对象的方法中,除了ModelAndView之外,其实其他的三个方法都是被同一个对象进行了实例化

1
2
3
4
5
6
@RequestMapping("/target")
public String target(ModelMap modelMap){
modelMap.addAttribute("modelmap","hello modelmap");
System.out.println(modelMap.getClass().getName());
return "target";
}

image-20220425102258113

image-20220425102421872

而modelMap继承了 LinkedHashMap,LinkedHashMap实现了接口map

image-20220425102605199

1
2
3
4
public interface Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {}

源码

我们在SpringMvc中启动debug模式,并在dispathcher中打断点,其实不管我们使用什么方法进行域对象的保存或者打开什么网页,我们都会经过ModelANDViewimage-20220425105123718

Session共享数据

使用原生的api,HttpSession session

application共享数据

对应整个工程,在服务器启动时就创建了,使用方法域Session相同

SpringMVC视图

服务器内部转发与客户端重定向 | 偷掉月亮 (moonshuo.cn)转发是服务器的一次请求,而重定向则是两次请求,同时重定向可以重定向到任何页面,但是转发只能转发给系统的组件进行处理,而WEB-INF的文件资源是不能被直接访问的,也就是不能通过重定向进行访问,但是注意虽然转发与重定向的看起来效果相同,但是地址栏的信息不会一样

转发视图

SpringMVC中默认的转发视图是InternalResourceView,转发是浏览器的一次请求,最终的地址为最终要展现的地址

1
2
3
4
5
6
7
8
9
10
//这个的逻辑处理满足不了条件,需要交给另外 一个子组件进行处理,使用forward:/请求的功能对应的操作,此过程会产生两次视图请求,但是浏览器仅仅响应了一次
@RequestMapping("/InternalResource")
public String InternalResource(){
return "forward:/testHello";
}

@RequestMapping("/testHello")
public String testHello(){
return "转发目标页面";
}
1
2
3
4
5
<body>
<a th:href="@{/InternalResource}">转发</a>
<a th:href="@{/Redirect}">重定向</a>

</body>

image-20220425122155614

重定向视图

SpringMVC中默认的重定向视图是RedirectView,重定向是两次请求,发送之后,最终的地址为???//testHello,在这个过程中浏览器发送了两次请求,???/Redirect地址进行了重定向,告诉浏览器去访问???/testHello

1
2
3
4
5
6
7
8
9
@RequestMapping("/Redirect")
public String Redirect(){
return "redirect:/testHello";
}

@RequestMapping("/testHello")
public String testHello(){
return "重定向的目标页面";
}

image-20220425122352589

视图控制器

当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示,即下面的两个程序效果相同

1
2
3
4
@RequestMapping( value = {"/hi"})
public String index(){
return "index";
}
1
2
3
4
5
<mvc:view-controller path="/hi" view-name="index"></mvc:view-controller>
<!--如果浏览器发送的信息,dispatcherservlet处理不了,则交给defaultservlet处理,开启对静态资源的访问和默认驱动-->
<mvc:default-servlet-handler/>
<!--开启注解驱动,要这两个标签同时使用-->
<mvc:annotation-driven/>