当前位置: 首页 > article >正文

Springboot之RequestAttributes学习笔记

RequestAttributes 和 ServletRequestAttributes 是 Spring 框架中用于处理请求作用域属性的核心接口和实现类。以下是它们的源码解读和关键点分析:
 

1. RequestAttributes 接口

RequestAttributes 是一个抽象接口,定义了在请求作用域内存储和获取属性的基本方法。
核心方法:

// 设置属性到指定的作用域(如请求或会话)
void setAttribute(String name, Object value, int scope);

// 获取指定作用域中的属性
Object getAttribute(String name, int scope);

// 移除指定作用域中的属性
void removeAttribute(String name, int scope);

// 注册销毁回调(通常用于清理资源)
void registerDestructionCallback(String name, Runnable callback, int scope);

// 获取会话ID
String getSessionId();

// 获取会话互斥对象(用于同步控制)
Object getSessionMutex();

作用域常量:
SCOPE_REQUEST: 表示请求作用域。
SCOPE_SESSION: 表示会话作用域。
设计目的:
RequestAttributes 提供了一个通用的抽象,使得开发者可以在不同的环境中(如 Servlet、Portlet 等)以统一的方式访问请求作用域的数据。
 


2. ServletRequestAttributes 实现类

ServletRequestAttributes 是 RequestAttributes 的具体实现,基于 Servlet API 提供了对 HTTP 请求和会话的支持。
核心字段:

private final HttpServletRequest request; // 当前的 HTTP 请求对象
private HttpServletResponse response;    // 当前的 HTTP 响应对象
private volatile HttpSession session;     // 当前的会话对象

核心方法实现:

设置属性:

  @Override
  public void setAttribute(String name, Object value, int scope) {
      if (scope == SCOPE_REQUEST) {
          this.request.setAttribute(name, value);
      } else if (scope == SCOPE_SESSION) {
          HttpSession session = getSession(true);
          session.setAttribute(name, value);
      } else {
          throw new IllegalArgumentException("Invalid scope: " + scope);
      }
  }
  

获取属性:

  @Override
  public Object getAttribute(String name, int scope) {
      if (scope == SCOPE_REQUEST) {
          return this.request.getAttribute(name);
      } else if (scope == SCOPE_SESSION) {
          HttpSession session = getSession(false);
          return (session != null ? session.getAttribute(name) : null);
      } else {
          throw new IllegalArgumentException("Invalid scope: " + scope);
      }
  }
  

移除属性:

  @Override
  public void removeAttribute(String name, int scope) {
      if (scope == SCOPE_REQUEST) {
          this.request.removeAttribute(name);
      } else if (scope == SCOPE_SESSION) {
          HttpSession session = getSession(false);
          if (session != null) {
              session.removeAttribute(name);
          }
      } else {
          throw new IllegalArgumentException("Invalid scope: " + scope);
      }
  }
  

获取会话ID:

  @Override
  public String getSessionId() {
      return getSession(true).getId();
  }
  

特性:

线程绑定:ServletRequestAttributes 通常与 RequestContextHolder 配合使用,通过 ThreadLocal 将请求上下文绑定到当前线程。
延迟加载会话:只有在需要时才会创建会话(通过 getSession(true) 或 getSession(false) 控制)。
 

3. RequestContextHolder 工具类


RequestAttributes 和 ServletRequestAttributes 通常通过 RequestContextHolder 来管理和访问。
核心方法:

// 获取当前线程的 RequestAttributes
public static RequestAttributes getRequestAttributes();

// 获取当前线程的 RequestAttributes,并强制要求不为空
public static RequestAttributes currentRequestAttributes();

4.使用案例

 private void printRequestContext() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes != null) {
            HttpServletRequest request = servletRequestAttributes.getRequest();
            HttpSession session = request.getSession();

            System.out.println("Request headers: ==>\n");
            request.getHeaderNames().asIterator().forEachRemaining(headerName -> {
                System.out.println(headerName + ": " + request.getHeader(headerName));
            });

            System.out.println("Request attributes: ==> \n");
            request.getAttributeNames().asIterator().forEachRemaining(attributeName -> {
                System.out.println(attributeName + ": " + request.getAttribute(attributeName));
            });

            System.out.println("Cookies: ==> \n");
            Arrays.stream(request.getCookies()).forEach(System.out::println);

            System.out.println("uri: ==> " + request.getRequestURI());
            System.out.println("url: ==> " + request.getRequestURL());

            System.out.println("Session Attributes: ==> \n");
            session.getAttributeNames().asIterator().forEachRemaining(attributeName -> {
                System.out.println(attributeName + ": " + session.getAttribute(attributeName));
            });

        }
    }

返回结果如下:

Request headers: ==>

accept: */*
accept-encoding: gzip, deflate, br
user-agent: PostmanRuntime-ApipostRuntime/1.1.0
connection: keep-alive
cookie: JSESSIONID=97CC336BA78105DAFF9D6AC07B1A4A06
cache-control: no-cache
host: localhost:6085


Request attributes: ==> 

org.springframework.web.servlet.View.pathVariables: {lang=zh_CN}
org.springframework.web.context.request.async.WebAsyncManager.WEB_ASYNC_MANAGER: org.springframework.web.context.request.async.WebAsyncManager@4c504320
org.springframework.web.servlet.HandlerMapping.bestMatchingHandler: com.vorwerk.cookidoo.cn.cms.controller.HomeController#homePageLayout(String)
org.springframework.web.servlet.DispatcherServlet.CONTEXT: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2b8bb184, started on Sat Mar 22 11:11:21 CST 2025

...
 

Cookies: ==> 

jakarta.servlet.http.Cookie@f14c39ba{JSESSIONID=97CC336BA78105DAFF9D6AC07B1A4A06,null}

uri: ==> /zh_CN/homepage
url: ==> http://localhost:6085/zh_CN/homepage


Session Attributes: ==> 

5. 总结

RequestAttributes 是一个抽象接口,定义了操作请求作用域属性的标准方法。
ServletRequestAttributes 是基于 Servlet API 的具体实现,提供了对 HTTP 请求和会话的直接支持。
RequestContextHolder 是一个工具类,用于在当前线程中访问和管理 RequestAttributes。
通过这些组件,Spring 提供了一种灵活且解耦的方式来处理请求作用域数据,适用于各种 Web 应用场景。


http://www.kler.cn/a/596823.html

相关文章:

  • 【深度学习入门_机器学习理论】梯度提升决策树(GBDT)
  • 【算法学习之路】13.BFS
  • 【go】如何处理可选配置
  • CSS 中@media查询的工作原理,如何利用它实现不同设备的样式适配
  • 大数据平台上的数据建模与分析:从数据到决策的跃迁
  • 旋转编码器
  • 基于随机森林回归预测葡萄酒质量
  • OpenCV中的矩阵操作
  • OSASIS(One-Shot Structure-Aware Stylized Image Synthesis)
  • 计算机网络性能优化相关内容详解
  • JavaScript基础-API 和 Web API
  • QT笔记----QCheckBox
  • 零、ubuntu20.04 安装 anaconda
  • 100道C#高频经典面试题及答案解析:C#程序员面试题库分类总结
  • 《通用去条纹算法:兼容自然图像与荧光图像的频域滤波方法》
  • 适配器模式 (Adapter Pattern)
  • 通俗一点介绍什么是场外期权交易 ?
  • 自动化测试框架pytest+requests+allure
  • 9.使用库
  • Android开源库——Glide