SpringMVC —— 4、域对象共享数据

目录

0、准备工作:创建模块并配置

1、回顾域对象

2、使用 ServletAPI 向 request 域对象共享数据(不建议使用)

 3、使用ModelAndView向request域对象共享数据(建议使用)

 4、使用Model向request域对象共享数据

 5、使用map向request域对象共享数据

 6、使用ModelMap向request域对象共享数据

 7、Model、ModelMap、Map的关系

8、控制器方法执行后都会返回统一的 ModelAndView 对象

9、向session域共享数据

 10、向application域(ServletContext域)共享数据


0、准备工作:创建模块并配置

① 创建目录如下:

 ②  TestController 类的内容如下:

@Controller
public class TestController {

    @RequestMapping("/")
    public String index(){
        return "index";
    }

}

③ springMVC.xml 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cntext="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置扫描组件 -->
    <cntext:component-scan base-package="com.zyj.mvc.controller"></cntext:component-scan>

    <!-- 配置Thymeleaf视图解析器 -->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">

                        <!-- 视图前缀 -->
                        <property name="prefix" value="/WEB-INF/templates/"/>

                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8" />
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

</beans>

 ④ index.html 内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
</body>
</html>

⑤ web.xml 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置编码过滤器 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置SpringMVC的前端控制器DispatcherServlet -->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

1、回顾域对象

四大域对象:

1、pageContext (PageContextImpl 类) :当前 jsp 页面范围内有效,由于 jsp 已经过时,在 SpringMVC 中不加以使用

2、request (HttpServletRequest 类) :一次请求内有效

3、session (HttpSession 类):一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)

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

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

:钝化与活化实际上就是session的序列化与反序列化。详细可以参考博客:Session 的钝化与活化_点滴记录-CSDN博客_session钝化和活化

4、application (ServletContext 类) :整个 web 工程(应用)范围内都有效(只要 web 工程不停止,数据都在),在服务器启动时创建,关闭时销毁。由于范围太大也少用。

域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。

虽然四个域对象都可以存取数据。在使用上它们是有优先顺序的。

四个域在使用的时候,优先顺序是,他们从小到大的范围的顺序。:
        pageContext ====>>> request ====>>> session ====>>> application

2、使用 ServletAPI 向 request 域对象共享数据(不建议使用)

① 创建 ScopeController 控制器类,内容如下:

@Controller
public class ScopeController {

    // 测试使用ServletAPI向request域对象共享数据
    @RequestMapping("/testRequestByServletAPI")
    public String testRequestByServletAPI(HttpServletRequest request){
        request.setAttribute("testRequestScope", "hello,ServletAPI");
        return "success";
    }

}

② 创建 success.html 页面,用来测试跳转是否成功

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
    这是success.html页面<br>
    <p th:text="${testRequestScope}"></p>
</body>
</html>

注:p 标签报错是正常现象,如果不让它报错,可以在 设置-编辑器-检查 中进行设置,如下图:取消打勾即可

 ③ 最后在首页 index.html 中添加测试的跳转链接

    <!-- 测试使用ServletAPI向request域对象共享数据 -->
    <a th:href="@{/testRequestByServletAPI}">测试使用ServletAPI向request域对象共享数据</a>

 ④ 结果如下图,传输成

 3、使用ModelAndView向request域对象共享数据(建议使用)

 ① 在 ScopeController 类中添加方法

    // 测试使用ModelAndView向request域对象共享数据
    // 注意使用该方法必须返回 ModelAndView 对象
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        ModelAndView mav = new ModelAndView();
        // 处理模型数据:即向请求域request共享数据
        mav.addObject("testRequestScope", "hello,ModelAndView");
        // 设置视图名称
        mav.setViewName("success");
        return mav;
    }

② 在首页 index.html 中添加测试的跳转链接

    <!-- 测试使用ModelAndView向request域对象共享数据 -->
    <a th:href="@{/testModelAndView}">测试使用ModelAndView向request域对象共享数据</a><br>

③ success.html 页面不变,运行测试,结果如下,传输成功

 4、使用Model向request域对象共享数据

① 在 ScopeController 类中添加方法

    // 测试使用Model向request域对象共享数据
    @RequestMapping("/testModel")
    public String testModel(Model model){
        model.addAttribute("testRequestScope", "hello,model");
        return "success";
    }

② 在首页 index.html 中添加测试的跳转链接

    <!-- 测试使用Model向request域对象共享数据 -->
    <a th:href="@{/testModel}">测试使用Model向request域对象共享数据</a><br>

③ success.html 页面不变,运行测试,结果如下,传输成功

 5、使用map向request域对象共享数据

在方法的形参中添加 Map 类型的数据,向 map 中存储的数据就是向 request 域中共享的数据

① 在 ScopeController 类中添加方法

    // 测试使用map向request域对象共享数据
    @RequestMapping("testMap")
    public String testMap(Map<String, Object> map){
        map.put("testRequestScope", "hello,map");
        return "success";
    }

② 在首页 index.html 中添加测试的跳转链接

    <!-- 测试使用map向request域对象共享数据 -->
    <a th:href="@{/testMap}">测试使用map向request域对象共享数据</a><br>

③ success.html 页面不变,运行测试,结果如下,传输成功

 6、使用ModelMap向request域对象共享数据

① 在 ScopeController 类中添加方法

    // 测试使用ModelMap向request域对象共享数据
    @RequestMapping("/testModelMap")
    public String testModelMap(ModelMap modelMap){
        modelMap.addAttribute("testRequestScope", "hello,ModelMap");
        return "success";
    }

② 在首页 index.html 中添加测试的跳转链接

    <!-- 测试使用ModelMap向request域对象共享数据 -->
    <a th:href="@{/testModelMap}">测试使用ModelMap向request域对象共享数据</a><br>

③ success.html 页面不变,运行测试,结果如下,传输成功

 7、Model、ModelMap、Map的关系

在上方使用这三种共享数据的方法中输出对应的形参,结果如下(注释为输出的结果)

        System.out.println(model); //{testRequestScope=hello,model}
        System.out.println(map); //{testRequestScope=hello,map}
        System.out.println(modelMap); //{testRequestScope=hello,ModelMap}

可以发现输出的格式一样,再输出对应形参的全类名(实现类),结果如下:

        System.out.println(model.getClass().getName()); //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(map.getClass().getName()); //org.springframework.validation.support.BindingAwareModelMap
        System.out.println(modelMap.getClass().getName()); //org.springframework.validation.support.BindingAwareModelMap

可以发现这三个的实现类都一样

查看 ModelMap类 的层次结构

//  查看 BindingAwareModelMap 类的源码,发现如下
public class BindingAwareModelMap extends ExtendedModelMap {}

// 查看 ExtendedModelMap 类的源码,发现如下,所以 BindingAwareModelMap 可以实例化 ModelMap 和 Model
public class ExtendedModelMap extends ModelMap implements Model {}

// 查看 ModelMap 的源码,发现如下,而 LinkedHashMap 又实现了 Map 接口,所以 BindingAwareModelMap 可以实例化 Map
public class ModelMap extends LinkedHashMap<String, Object> {}
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {}

总结

Model、ModelMap、Map类型的参数其实本质上都是 BindingAwareModelMap 类型的

8、控制器方法执行后都会返回统一的 ModelAndView 对象

    // 测试使用ServletAPI向request域对象共享数据
    @RequestMapping("/testRequestByServletAPI")
    public String testRequestByServletAPI(HttpServletRequest request){
        request.setAttribute("testRequestScope", "hello,ServletAPI");
        return "success";
    }

在上述方法的任一行打上断点,根据前面所学,我们知道请求分发和处理都是通过 DispatcherServlet 进行的,在调试器中找到与 DispatcherServlet 有关的方法并点击,发现跳转到 mv 属性上,而 mv 是 ModelAndView 对象,所以最后会返回 ModelAndView 对象

其他控制器方法也是一样,在方法任一行打上断点进行调试,都可以在调试器的方法堆中找到上述方法,且都是 mv 这一行,所以控制器方法执行后都会返回统一的 ModelAndView 对象

9、向session域共享数据

这里通过 ServletAPI 向session域共享数据

① 在 ScopeController 类中添加方法

    // 测试向session域共享数据
    @RequestMapping("/testSession")
    public String testSession(HttpSession session){
        session.setAttribute("testSessionScope", "hello,session");
        return "success";
    }

② 在首页 index.html 中添加测试的跳转链接

    <!-- 测试向session域共享数据 -->
    <a th:href="@{/testSession}">测试向session域共享数据</a><br>

③ 在 success.html 页面添加显示 Session 域的内容

    <p th:text="${session.testSessionScope}"></p>

④ 运行测试,结果如下,传输成功

 10、向application域(ServletContext域)共享数据

① 在 ScopeController 类中添加方法

    // 测试向application域(ServletContext域)共享数据
    @RequestMapping("/testApplication")
    public String testApplication(HttpSession session){
        ServletContext application = session.getServletContext();
        application.setAttribute("testApplicationScope", "hello,application");
        return "success";
    }

② 在首页 index.html 中添加测试的跳转链接

    <!-- 测试向application域(ServletContext域)共享数据 -->
    <a th:href="@{/testApplication}">测试向application域(ServletContext域)共享数据</a><br>

③ 在 success.html 页面添加显示 Session 域的内容

    <p th:text="${application.testApplicationScope}"></p>

 ④ 运行测试,结果如下,传输成功

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值