SpringMVC(四)域对象共享数据

pageContext:表示的是jsp页面的范围

HttpServletRequest:表示的是一次请求的范围

HttpSession:表示的是一次会话的范围

ServletContext:表示的是整个应用的范围

一、向请求域中共享数据:

1.1使用ServletAPI向request域对象共享数据

java 复制代码
 @RequestMapping("testServletAPI")
    public String testServletAPI(HttpServletRequest request){
        request.setAttribute("testScope","hello,servletAPI");
        return  "success";
    }

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

java 复制代码
package com.rgf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class TestScopeController {
    @RequestMapping("test/mav")
    public ModelAndView testMav(){
        /**
         * ModelAndView包含Model和View的功能
         * Model主要用于向请求域共享数据
         * View主要用于设置逻辑视图,实现页面跳转
         */
        ModelAndView mav = new ModelAndView();
        //向请求域共享数据
        mav.addObject("testRequestScope","Hello,ModelAndView");
        //设置逻辑视图,实现页面跳转
        mav.setViewName("success");
        return mav;
    }
}

我们设置在跳转页面进行获取数据:

java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>success.html</h1>
<p th:text="${testRequestScope}"></p>
</body>
</html>

同时我们在首页中输入如下所示:

java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br>
<a th:href="@{/abc}">测试@RequestMapping注解的value属性</a>
<form th:action="@{/hello}" method="post">
    <input type="submit" value="测试@RequestMapping注解的method属性">
</form>
<a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br>
<a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br>
<a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br>
<br>
<form th:action="@{/param/servletAPI}" method="post">
    用户名: <input type="text" name="username"><br>
    密码:   <input type="password" name="password"><br>
    提交: <input type="submit" value="登录"><br>
</form>
<a th:href="@{/param/servletAPI}"></a>
<hr>
<a th:href="@{/test/mav}">测试通过ModelAndView向请求域共享数据</a>
</body>
</html>

我们进行运行:

我们点击ModelAndView的链接,跳转之后,如下所示:

success.html

Hello,ModelAndView

1.3使用Model向请求域共享数据

我们进行如下操作:

java 复制代码
 @RequestMapping("/test/model")
    public String testModel(Model model){
        model.addAttribute("testRequestScope","hello,Model");
        return  "success";
        
    }

我们的返回success界面:

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>success.html</h1>
<p th:text="${testRequestScope}"></p>
</body>
</html>

我们的首页如下所示:

java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br>
<a th:href="@{/abc}">测试@RequestMapping注解的value属性</a>
<form th:action="@{/hello}" method="post">
    <input type="submit" value="测试@RequestMapping注解的method属性">
</form>
<a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br>
<a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br>
<a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br>
<br>
<form th:action="@{/param/servletAPI}" method="post">
    用户名: <input type="text" name="username"><br>
    密码:   <input type="password" name="password"><br>
    提交: <input type="submit" value="登录"><br>
</form>
<a th:href="@{/param/servletAPI}"></a>
<hr>
<a th:href="@{/test/mav}">测试通过ModelAndView向请求域共享数据</a>
<a th:href="@{/test/model}">测试通过Model向请求域共享数据</a>
</body>
</html>

登陆首页点击链接之后:

我们点击链接之后进入到成功界面:

该成功界面展示如下所示:

复制代码
hello,Model

1.4使用ModelMap向请求域共享数据

我们设置如下所示:

java 复制代码
 @RequestMapping("/test/modelMap")
    public String testModelMap(ModelMap modelMap){
        modelMap.addAttribute("testRequestScope","hello,ModelMap");
        return  "success";

    }

首页设置如下所示:

java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br>
<a th:href="@{/abc}">测试@RequestMapping注解的value属性</a>
<form th:action="@{/hello}" method="post">
    <input type="submit" value="测试@RequestMapping注解的method属性">
</form>
<a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br>
<a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br>
<a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br>
<br>
<form th:action="@{/param/servletAPI}" method="post">
    用户名: <input type="text" name="username"><br>
    密码:   <input type="password" name="password"><br>
    提交: <input type="submit" value="登录"><br>
</form>
<a th:href="@{/param/servletAPI}"></a>
<hr>
<a th:href="@{/test/mav}">测试通过ModelAndView向请求域共享数据</a><br>
<a th:href="@{/test/model}">测试通过Model向请求域共享数据</a><br>
<a th:href="@{/test/modelMap}">测试通过ModelMap向请求域共享数据</a><br>
</body>
</html>

成功界面如下所示:

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>success.html</h1>
<p th:text="${testRequestScope}"></p>
</body>
</html>

登陆首页点击链接之后:

我们的成功界面返回如下所示:

复制代码
hello,ModelMap

1.5使用map向请求域共享数据

java 复制代码
  @RequestMapping("/test/map")
    public String testMap(Map<String,Object> map){
        map.put("testRequestScope","hello,Map");
        return  "success";

    }

首页如下所示:

java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br>
<a th:href="@{/abc}">测试@RequestMapping注解的value属性</a>
<form th:action="@{/hello}" method="post">
    <input type="submit" value="测试@RequestMapping注解的method属性">
</form>
<a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br>
<a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br>
<a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br>
<br>
<form th:action="@{/param/servletAPI}" method="post">
    用户名: <input type="text" name="username"><br>
    密码:   <input type="password" name="password"><br>
    提交: <input type="submit" value="登录"><br>
</form>
<a th:href="@{/param/servletAPI}"></a>
<hr>
<a th:href="@{/test/mav}">测试通过ModelAndView向请求域共享数据</a><br>
<a th:href="@{/test/model}">测试通过Model向请求域共享数据</a><br>
<a th:href="@{/test/modelMap}">测试通过ModelMap向请求域共享数据</a><br>
<a th:href="@{/test/map}">测试通过map向请求域共享数据</a><br>
</body>
</html>

点击首页链接:

跳转到成功界面展示如下所示:

hello,Map

我们通过如下所示查看后三种方式的关系:

java 复制代码
package com.rgf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@Controller
/**
 * 向域对象共享数据:
 * 1.通过ModelAndView向请求域共享数据
 * 使用ModelAndView时,可以使用其Model功能向请求域共享数据
 * 使用View功能设置逻辑视图,但是控制方法一定要将ModelAndView作为方法的返回值
 * 2.使用Model向请求域共享数据
 * 3.使用ModelMap向请求域共享数据
 * 4.使用map向请求域共享数据
 *
 */
public class TestScopeController {
    @RequestMapping("test/mav")
    public ModelAndView testMav(){
        /**
         * ModelAndView包含Model和View的功能
         * Model主要用于向请求域共享数据
         * View主要用于设置逻辑视图,实现页面跳转
         */
        ModelAndView mav = new ModelAndView();
        //向请求域共享数据
        mav.addObject("testRequestScope","Hello,ModelAndView");
        //设置逻辑视图,实现页面跳转
        mav.setViewName("success");
        return mav;
    }


    @RequestMapping("/test/model")
    public String testModel(Model model){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(model.getClass().getName());
        model.addAttribute("testRequestScope","hello,Model");
        return  "success";

    }

    @RequestMapping("/test/modelMap")
    public String testModelMap(ModelMap modelMap){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(modelMap.getClass().getName());
        modelMap.addAttribute("testRequestScope","hello,ModelMap");
        return  "success";

    }

    @RequestMapping("/test/map")
    public String testMap(Map<String,Object> map){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(map.getClass().getName());
        map.put("testRequestScope","hello,Map");
        return  "success";

    }
}

我们发现所输出的类为同一个,我们来查看其中的关系:

org.springframework.validation.support.BindingAwareModelMap

连续按键两次shift进行查找类:

我们进行查看该类的继承关系:

我们总结如下所示:

java 复制代码
package com.rgf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@Controller
/**
 * 向域对象共享数据:
 * 1.通过ModelAndView向请求域共享数据
 * 使用ModelAndView时,可以使用其Model功能向请求域共享数据
 * 使用View功能设置逻辑视图,但是控制方法一定要将ModelAndView作为方法的返回值
 * 2.使用Model向请求域共享数据
 * 3.使用ModelMap向请求域共享数据
 * 4.使用map向请求域共享数据
 * 5.Model和ModelMap和map的关系
 * 其实在底层中,这些类型的形参最终都是通过BindingAwareModelMap创建
 * public class BindingAwareModelMap extends ExtendedModelMap{}
 * public class ExtendedModelMap extends ModelMap implements Model {}
 * public class ModelMap extends LinkedHashMap<String, Object> {}
 * public class LinkedHashMap<K,V>   extends HashMap<K,V>   implements Map<K,V>  {}
 * 
 */
public class TestScopeController {
    @RequestMapping("test/mav")
    public ModelAndView testMav(){
        /**
         * ModelAndView包含Model和View的功能
         * Model主要用于向请求域共享数据
         * View主要用于设置逻辑视图,实现页面跳转
         */
        ModelAndView mav = new ModelAndView();
        //向请求域共享数据
        mav.addObject("testRequestScope","Hello,ModelAndView");
        //设置逻辑视图,实现页面跳转
        mav.setViewName("success");
        return mav;
    }


    @RequestMapping("/test/model")
    public String testModel(Model model){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(model.getClass().getName());
        model.addAttribute("testRequestScope","hello,Model");
        return  "success";

    }

    @RequestMapping("/test/modelMap")
    public String testModelMap(ModelMap modelMap){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(modelMap.getClass().getName());
        modelMap.addAttribute("testRequestScope","hello,ModelMap");
        return  "success";

    }

    @RequestMapping("/test/map")
    public String testMap(Map<String,Object> map){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(map.getClass().getName());
        map.put("testRequestScope","hello,Map");
        return  "success";

    }
}

二、向session域共享数据、向application域共享数据

可以使用servletAPI实现向session域共享数据,比较简便。

java 复制代码
 @RequestMapping("/param/servletAPI")
    public  String getParamByServletAPI(HttpServletRequest request){
        HttpSession session = request.getSession();
        String username = request.getParameter("username");
        String password=request.getParameter("password");
        System.out.println("username:"+username+",password:"+password);
        return "success";
    }
java 复制代码
package com.rgf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
/**
 * 向域对象共享数据:
 * 1.通过ModelAndView向请求域共享数据
 * 使用ModelAndView时,可以使用其Model功能向请求域共享数据
 * 使用View功能设置逻辑视图,但是控制方法一定要将ModelAndView作为方法的返回值
 * 2.使用Model向请求域共享数据
 * 3.使用ModelMap向请求域共享数据
 * 4.使用map向请求域共享数据
 * 5.Model和ModelMap和map的关系
 * 其实在底层中,这些类型的形参最终都是通过BindingAwareModelMap创建
 * public class BindingAwareModelMap extends ExtendedModelMap{}
 * public class ExtendedModelMap extends ModelMap implements Model {}
 * public class ModelMap extends LinkedHashMap<String, Object> {}
 * public class LinkedHashMap<K,V>   extends HashMap<K,V>   implements Map<K,V>  {}
 *
 */
public class TestScopeController {
    @RequestMapping("test/mav")
    public ModelAndView testMav(){
        /**
         * ModelAndView包含Model和View的功能
         * Model主要用于向请求域共享数据
         * View主要用于设置逻辑视图,实现页面跳转
         */
        ModelAndView mav = new ModelAndView();
        //向请求域共享数据
        mav.addObject("testRequestScope","Hello,ModelAndView");
        //设置逻辑视图,实现页面跳转
        mav.setViewName("success");
        return mav;
    }


    @RequestMapping("/test/model")
    public String testModel(Model model){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(model.getClass().getName());
        model.addAttribute("testRequestScope","hello,Model");
        return  "success";

    }

    @RequestMapping("/test/modelMap")
    public String testModelMap(ModelMap modelMap){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(modelMap.getClass().getName());
        modelMap.addAttribute("testRequestScope","hello,ModelMap");
        return  "success";

    }

    @RequestMapping("/test/map")
    public String testMap(Map<String,Object> map){
        //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(map.getClass().getName());
        map.put("testRequestScope","hello,Map");
        return  "success";
    }

    @RequestMapping("/test/session")
    public  String testSession(HttpSession session){
        session.setAttribute("testSessionScope","hello,Session");
        return "success";
    }

    @RequestMapping("/test/application")
    public  String testApplication(HttpSession session){
        ServletContext servletContext = session.getServletContext();
        servletContext.setAttribute("testApplicationScope","hello,Application");
        return "success";
    }

}
java 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br>
<a th:href="@{/abc}">测试@RequestMapping注解的value属性</a>
<form th:action="@{/hello}" method="post">
    <input type="submit" value="测试@RequestMapping注解的method属性">
</form>
<a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br>
<a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br>
<a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br>
<br>
<form th:action="@{/param/servletAPI}" method="post">
    用户名: <input type="text" name="username"><br>
    密码:   <input type="password" name="password"><br>
    提交: <input type="submit" value="登录"><br>
</form>
<a th:href="@{/param/servletAPI}"></a>
<hr>
<a th:href="@{/test/mav}">测试通过ModelAndView向请求域共享数据</a><br>
<a th:href="@{/test/model}">测试通过Model向请求域共享数据</a><br>
<a th:href="@{/test/modelMap}">测试通过ModelMap向请求域共享数据</a><br>
<a th:href="@{/test/map}">测试通过map向请求域共享数据</a><br>
<a th:href="@{/test/session}">测试向会话域共享数据</a><br>
<a th:href="@{/test/application}">测试向应用域共享数据</a><br>
</body>
</html>
java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>success.html</h1>
<!--获取请求域中的数据-->
<p th:text="${testRequestScope}"></p>
<!--获取会话域中的数据-->
<p th:text="${session.testSessionScope}"></p>
<!--获取应用域中的数据-->
<p th:text="${application.testApplicationScope}"></p>
</body>
</html>

我们来进行测试:

我们运行之后进行点击:

我们进行点击,点击测试向会话域共享数据的时候出现:hello,Session

我们进行点击,点击测试向应用域(当前我们服务器运行的整个过程中)共享数据的时候出现:

hello,Session

hello,Application

一次会话是浏览器开启到浏览器关闭的过程。未关闭浏览器则会一直存在。

我们将网址复制下来之后,再次运行之后仍然会出现hello,application.

我们重新编译的时候则会清空session和application里面的值。

如果重新运行不清空session和application值,我们需要这么进行设置:

选择之后则会使用session的钝化和活化功能。

session的钝化和活化:

session的钝化

当前的服务器关闭之后,session中的数据会被钝化到我们当前的磁盘文件上,钝化到tomcat里面的work目录来存放sesion的钝化文件的,还有我们的jsp所翻译成的servlet.当前服务器重新启动后,会把钝化文件中的数据重新加载到session中。所以服务器关闭的话,只要浏览器不关闭,session就可以钝化和活化。哪怕服务器关掉,session中的数据也不会消失。

当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件("SESSIONS.ser")的形式存储在tomcat 的work 目录下,这个过程叫做Session 的钝化。

session的活化

当服务器再次正常开启时,服务器会找到之前的"SESSIONS.ser" 文件,从中恢复之前保存起来的Session 对象,这个过程叫做Session的活化。

如果在session中共享的是一个实体类类型的数据,必须将实体类实现一个序列化的接口。

如果在session中共享的是一个user对象,必须实现序列化的接口。(钝化是一个序列化的过程)

相关推荐
拉玛干5 小时前
社团周报系统可行性研究-web后端框架对比-springboot,django,gin
数据库·python·spring·golang
程序员大金7 小时前
基于SSM+Vue+MySQL的酒店管理系统
前端·vue.js·后端·mysql·spring·tomcat·mybatis
努力的布布7 小时前
Spring源码-从源码层面讲解声明式事务的运行流程
java·spring
程序员大金7 小时前
基于SpringBoot的旅游管理系统
java·vue.js·spring boot·后端·mysql·spring·旅游
爱上语文7 小时前
Springboot三层架构
java·开发语言·spring boot·spring·架构
你知道“铁甲小宝”吗丶9 小时前
【第33章】Spring Cloud之SkyWalking服务链路追踪
java·spring boot·spring·spring cloud·skywalking
听封9 小时前
Thymeleaf 的创建
java·spring boot·spring·maven
huapiaoy10 小时前
Spring mvc
java·spring·mvc
你知道“铁甲小宝”吗丶11 小时前
【第34章】Spring Cloud之SkyWalking分布式日志
java·spring boot·spring·spring cloud·skywalking