Spring MVC - 域对象

 1. Servlet 域对象

    定义:可以在不同的 Servlet  中进行数据传递的对象就称为域对象。

    Servlet 里面一共有四个域对象,四个域对象分别是page对象,request对象,session对象,application对象,用于在同一范围内的不同组件之间传递和共享数据。这些域对象使得数据能够在不同的请求处理过程中被访问和修改,从而支持多种 Web 应用的数据交互需求。

void setAttribute(String name, Object value);  // 存储数据
Object getAttribute(String name);              // 获取数据
void removeAttribute(String name);             // 删除数据
//这三个方法是对域对象进行数据操作的三个方法,四个域对象作用范围从小到大是:
 page < request < session < application

1.1 request (请求域)

对象名称:HttpServletRequest

request 对象代表一个请求,每次请求都是一个新的request对象。请求来时创建 request ,请求结束销毁 request。

业务场景:A资源通过转发的方式跳转到B资源,因为时转发的形式,所以A到B是一个请求,如果A资源和B资源想共享一个数据,那么需要将数据存储到 request 域中。

1.2 session (会话域)

对象名称:HttpSession

session 对象代表了一次会话,从浏览器打开访问到浏览器关闭,这是一个完整的会话。每个 session 对象都对应一个 JSESSIONID,而 JSESSIONID 以 cookie 存储在浏览器客户端中,浏览器关闭,JSESSIONID 失效,会话结束。

如果 session 超过30分钟没有使用,就会被销毁;如果服务器非正常关闭,没有到期的session也会跟着销毁;如果调用session提供的invalidate(),可以立即销毁session。

业务场景:

  1.A资源通过重定向的方式跳转B资源,因为是重定向方式,A跳转B是两次请求,如果想让A和B资源共享同一个数据,可以将数据储存到 session 中。

  2.登陆后保持用户状态。

1.3 application (应用)

对象名称:ServletContext

application 对象代表了整个 web 服务应用,服务器启动时创建,应用关闭时销毁。对于一个 web 应用来说,application 对象只有一个。

业务场景:记录网站的在线人数。

2. request 域对象

注意!注意!注意!:如果controller层需要通过thymeleaf去访问页面,注入MvcController的注解必须为@Controller,而不是@RestConreoller(@ResponseBody+@Controller)注解。

提前准备工作:

通过thymeleaf来作为试图展示效果,配置thymeleaf在SpringBoot中配置:

1. 先导入thymeleaf依赖

2. 配置文件内容:  
Spring:
  thymeleaf:
    cache: false                     #不开启缓存
    prefix: classpath:/templates/    #配置文件前缀
    suffix: .html                    #配置文件后缀
    mode: HTML                       #配置文件格式
    encoding: UTF-8                  #配置编码格式
    servlet:
      content-type: text/html 

3. 添加页面

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Servlet 域</title>
</head>
<div id="bottom-text">
    <h3> request 域对象效果展示  </h3>
    <p th:text="${msg}"></p>
</div>
</body>
</html>

2.1  使用 Servlet API 方式

第一种方式:在 Spring MVC 中使用 Servlet API 可以完成 request 域数据共享。方式:在处理器方法上添加  HttpServletRequest 参数即可。

    //伪代码
    @RequestMapping(value = {"/servletAPI"})
    public String toTestValue(HttpServletRequest request) {
        //将共享的数据存储到 request 域中,设置k-v格式,可以在其他页面直接获取msg这个名称获取相对应的值
        request.setAttribute("msg", "通过原生Servlet API 完成 request 域数据的共享");
        //跳转视图,在视图页面将 request 域中的数据取出来,这样就完成了 controller 和 view 两个组件在同一个请求中数据共享
        //这个跳转,默认是转发的方式: forward:
        return "request";
    }

2.2 使用 Model 接口

第二种方式:在 Spring MVC 中使用 Model 可以完成 request 域数据共享。方式:在处理器方法上添加 Model 参数即可。

    @RequestMapping("/model")
    public String model(Model model){
        //将共享的数据存储到 request 域中,设置k-v格式,可以在其他页面直接获取msg这个名称获取相对应的值
        model.addAttribute("msg","通过 model 来完成 request 域数据共享");
        //转发
        return "request";
    }

2.3 使用 Map 接口

第三种方式:在 Spring MVC 中使用 Map 可以完成 request 域数据共享。方式:在处理器方法上添加 Map 参数即可。

    @RequestMapping("/map")
    public String model(Map<String,Object> map){
        //将共享的数据存储到 request 域中,设置k-v格式,可以在其他页面直接获取msg这个名称获取相对应的值
        map.put("msg","通过 Map 来完成 request 域数据共享");
        return "request";
    }

2.4 使用 ModelMap 类

第四种方式:在 Spring MVC 中使用 ModelMap 可以完成 request 域数据共享。方式:在处理器方法上添加 ModelMap 参数即可。

    @RequestMapping("/modelMap")
    public String model(ModelMap modelMap){
        //将共享的数据存储到 request 域中,设置k-v格式,可以在其他页面直接获取msg这个名称获取相对应的值
        modelMap.addAttribute("msg","通过 modelMap 来完成 request 域数据共享");
        return "request";
    }

2.5 使用 ModelAndView 类

第五种方式:在 Spring MVC 中使用 ModelAndView 可以完成 request 域数据共享。方式:在处理器方法中创建 ModelAndView 对象,并将数据添加到请求域中,并指定跳转视图名称即可。

    /**
     * 注意:  返回值必须是ModelAndView
     * ModelAndView有Model和View的功能,Model主要用于向请求域共享数据,View主要用于设置视图,实现页面跳转
     */
    @RequestMapping("/modelAndView")
    public ModelAndView modelAndView(){
        //创建 ModelAndView 对象
        ModelAndView mav = new ModelAndView();
        //绑定数据
        mav.addObject("msg","通过 ModelAndView 来完成 request 域数据共享");
        //设置跳转视图,实现页面跳转
        mav.setViewName("request");
        return mav;
    }

2.6 Model、Map、ModelMap的关系

Model、modelMap、Map表面使用的是不同接口和不同的类,实际上底层都使用了同一个对象:org.springframework.validation.support.BindingAwareModelMap

BindingAwareModelMap 继承了 ExtendedModelMap 类

ExtendedModelMap 实现了 Model 接口

ExtendedModelMap 继承了 ModelMap 类

ModelMap 继承了 LinkedHashMap 类 继承了 HashMap 实现了 Map 接口

2.7 拓展

//对于处理器方法来说,不管你使用的参数是Model接口,还是Map接口,还是ModelMap类,还是创建ModelAndView类,最终处理器方法执行结束后,返回的都是ModelAndView对象,将这个对象交给DispatcherServlet类
//当请求路径不是JSP的时候,都会走DispatcherServlet(前端控制器)
//DispatcherServlet中有一个核心方法 doDispatch() 这个方法用来通过请求路径找到对应的处理器方法,然后调用处理器方法,处理器方法返回一个逻辑视图名称(也可能是ModelAndView对象),底层会将逻辑视图名称转为view对象,然后将model和view对象封装成一个ModelAndView对象,最后返回给DispatcherServlet

3. session 域对象

准备工作

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Servlet 域</title>
</head>
<div id="bottom-text">
    <h3> session 域对象效果展示  </h3>
    <!--在页面中就需要用session.key-->
    <p th:text="${session.msg}"></p>
</div>
</body>
</html>

3.1 使用 Servlet API 方式

在处理器方法的参数上添加 HttpSession 参数,Spring MVC 会自动将 session 对象传递给这个参数。

    @RequestMapping("/sessionA")
    public String sessionA(HttpSession session){
        //处理核心业务
        //向 session 中绑定数据
        session.setAttribute("msg","通过 Servlet API 方式共享 session 域对象数据!");
        //返回逻辑视图名称
        return "session";
    }

3.2 使用 @SessionAttributes 注解

在处理器上使用 @SessionAttributes 注解绑定要共享到 session 域的数据。处理器方法中的参数model、map、modelMap都可以。

@Slf4j
@Controller
@RequestMapping("/mvc")
@SessionAttributes(value = {"msg"})
public class MvcController {

    @RequestMapping("/sessionB")
    public String sessionB(Model model){
        //向会话中绑定数据
        model.addAttribute("msg" ,"Spring mvc 使用@SessionAttributes 注解完成 session 域数据共享");
        //返回视图名称
        return "session";
    }

}

4. application 域对象

   application域是最大的域,作用在整个工程里面。application就是ServletContext,它的获取方法很多,可以通过request获取,也可以通过session获取。

准备工作

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Servlet 域</title>
</head>
<div id="bottom-text">
    <h3> application 域对象效果展示  </h3>
    <!--前端页面需要使用application.key-->
    <p th:text="${application.msg}"></p>
</div>
</body>
</html>

使用 Servlet API 方式将数据共享到 application 域中,下面代码区别在于获取 application(ServletContext)对象的方式不同。

    @RequestMapping("/applicationByRequest")
    public String applicationA(HttpServletRequest request){   //通过request
        //通过 request 获取 ServletContext,就是 application
        ServletContext app = request.getServletContext(); 
        //将数据存储到 application 中
        app.setAttribute("msg", "在 SpingMVC 中通过 Servlet API 将数据共享到 application 域中");
        return "application";
    }

    @RequestMapping("/applicationBySession")
    public String applicationA(HttpSession session){            //通过session
        //通过 session 获取 ServletContext,就是 application
        ServletContext app =session.getServletContext();
        app.setAttribute("msg", "在 SpingMVC 中通过 Servlet API 将数据共享到 application 域中");
        return "application";
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值