SpringMVC使用域对象共享数据

目录

1、SpringMVC中的域对象

2、向request域对象共享数据的几种方式

(1)使用ServletAPI

(2)使用ModelAndView

(3)使用Model

(4)使用Map集合

(6)原理分析及总结

3、向session域对象共享数据

4、向servletContext域对象共享数据


1、SpringMVC中的域对象

此处只有request、session、servletContext被使用,而page是jsp页面的域,不使用jsp。

  • request:一次请求的范围内
  • session:一次会话的范围内
  • servletContext:整个web的应用范围内

2、向request域对象共享数据的几种方式

(1)使用ServletAPI

控制器方法存入数据

@RequestMapping("/testRequestByServletAPI")
public String testRequestByServletAPI(HttpServletRequest request){
    request.setAttribute("username", "zhangsan");
    request.setAttribute("password", "123456");

    return "success";
}

前端页面读取数据

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Success</title>
    </head>
    <body>
        <h3>success</h3><br>
        <p th:text="${username}"></p>
        <p th:text="${password}"></p>
    </body>
</html>

(2)使用ModelAndView

什么是ModelAndView

ModelAndView是一个类,可以利用它的对象设置当前请求的视图跳转数据共享

不管使用什么方式,Spring最终都会将模型数据和视图封装到ModelAndView中。

ModelAndView对象的作用

有两个功能。

Model:向request域中共享数据

View:设置视图跳转。可以设置视图名称(setViewName),也可以设置视图(setView)

示例

通过ModelAndView,向request域中存放数据

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
    ModelAndView mav = new ModelAndView();
    //处理模型数据,即向request域共享数据
    mav.addObject("username", "lisi");
    mav.addObject("password", "456789");

    //处理视图数据,即设置视图名称
    mav.setViewName("success");

    return mav;
}

读取数据和之前的前端页面一致

<p th:text="${username}"></p>
<p th:text="${password}"></p>

注意

如果在控制器方法中使用了ModelAndView对象,那么该mav对象必须作为方法的返回值返回

否则SpringMVC无法知晓你使用了ModelAndView

(3)使用Model

什么是Model

指的是ModelAndView中的Model

Model的作用

共享数据

示例

@RequestMapping("/testModel")
public String testModel(Model model){
    model.addAttribute("username", "wangwu");
    model.addAttribute("password", "555555");
    return "success";
}

注意

单独使用Model

  • 形参是Model类型
  • 返回值是String类型,返回视图名称

(4)使用Map集合

什么叫使用map向request域共享数据

之前将Model类型作为控制器方法的形参,通过设置model的参数,就达到了共享数据的效果。

如果使用Map集合,也是一样的效果。

将Map类型作为形参,方法体中给map添加键值对,也可以直接将键值对保存到域对象。

示例

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){

    map.put("username", "gaoliu");
    map.put("password", "666666");

    return "success";
}

(6)原理分析及总结

a. 为什么Model、ModelMap、Map,都能以同样的方式共享数据?

Model、ModelMap、Map类型的参数,其实本质上都是 BindingAwareModelMap 类型。这是Spring做的,并不是原生类型。

具体来说,它们实例化时,都用的是 BindingAwareModelMap 这个类。

那么Model、ModelMap、Map一定存在着联系。

先看Model的源码

public interface Model {...}

说明它是Spring中,模型部分的顶层接口。

ModelMap的源码

public class ModelMap extends LinkedHashMap<String, Object> {...}

它继承了LinkedHashMap,而LinkedHashMap实现了Map接口。所以ModelMap也属于一个Map接口的实现类

ModelMap的继承结构

BindAwareModelMap是ModelMap的子类,所以BindAwareModelMap可以实例化ModelMap。既然ModelMap实现了Map,那么BindAwareModelMap也可以实例化Map

BindAwareModelMap的继承结构

BindAwareModelMap的父类是ExtendedModelMap

public class ExtendedModelMap extends ModelMap implements Model {...}

ExtendedModelMap继承了ModelMap类,并且实现了Model接口,所以BindAwareModelMap可以实例化Model类型

总结

Model、ModelMap、Map的关系:

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

b.为什么这几种方式都没有指定request域,却都被称作向request域对象中共享数据?

首先,Model、ModelMap或是Map的方式,最终都会由SpringMVC封装成ModelAndView对象。

而使用ModelAndView的方式,是我们自己组装了ModelAndView对象并返回给了SpringMVC。

所以,这个问题的本质是,ModelAndView对象如何向request域对象中存放数据?

ModelandView是将 视图信息和数据封装到一起的,spring来解析ModelandView中的信息,包括视图和数据 ,然后将数据set到request里面,并且根据model里面的视图信息以及spring mvc的配置让request进行跳转。

3、向session域对象共享数据

使用ServletAPI比较简单

@RequestMapping("/testSession")
public String testSession(HttpSession session){
    session.setAttribute("username", "xiaowb");
    session.setAttribute("password", "000000");
    return "success";
}

前端获取session域对象中的值

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Success</title>
    </head>
    <body>
        <h3>success</h3><br>
        <p th:text="${session.username}"></p>
        <p th:text="${session.password}"></p>
    </body>
</html>

thymeleaf获取session域对象中的数据时,需要加session.键名

4、向servletContext域对象共享数据

注意

在jsp、Thymeleaf等模板引擎中,servletContext通常被叫做application,本质是一样的。

所以在获取servletContext对象时,最好也叫做application。

使用ServletAPI比较简单

@RequestMapping("/testSessionContext")
public String testServletContext(HttpSession session){
    ServletContext application = session.getServletContext();
    application.setAttribute("username", "xiaocs");
    application.setAttribute("password", "999999");
    return "success";
}

前端获取application域对象中的值

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Success</title>
    </head>
    <body>
        <h3>success</h3><br>
        <p th:text="${application.username}"></p>
        <p th:text="${application.password}"></p>
    </body>
</html>

thymeleaf获取application域对象中的数据时,需要加application.键名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值