1. 通过 RequestContextHolder 对象
package com.order.utils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author guoyiguang
* @description houqu Request duixiang he Response duixiang
* @date 2021/12/24$
*/
public class WebUtil {
/** 获取request对象 **/
public static HttpServletRequest getRequest(){
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null){
return null;
}
return ((ServletRequestAttributes)requestAttributes).getRequest();
}
/** 获取response对象 **/
public static HttpServletResponse getResponse(){
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null){
return null;
}
return ((ServletRequestAttributes)requestAttributes).getResponse();
}
}
理解:
对 RequestContextHolder 的理解:
RequestContextHolder 里有 ThreadLocal 对象,可以存放 线程的私有属性,如下:
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal<>("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal<>("Request context");
原理:
Servlet 监听器(RequestContextListener implements ServletRequestListener ) 监听请求,
HttpServletRequest 这个对象创建完之后,会把他作为 ServletRequestAttributes 构造器的参数 ,对 ServletRequestAttributes 进行实例化
这样通过 ServletRequestAttributes 和 HttpServletRequest 对象就就行了绑定
如下:(所在类: ServletRequestAttributes)
public ServletRequestAttributes(HttpServletRequest request) {
Assert.notNull(request, "Request must not be null");
this.request = request;
}
然后:作为线程的私有属性放到 ThreadLocal 里
inheritableRequestAttributesHolder.set(ServletRequestAttributes);
最后使用:
// 获取请求 对象
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null){
return null;
}
return ((ServletRequestAttributes)requestAttributes).getRequest();
// 获取响应 对象
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null){
return null;
}
return ((ServletRequestAttributes)requestAttributes).getResponse();
相关的监听器:
RequestContextListener implements ServletRequestListener extends EventListener
Thread里 有 ThreadLocalMap 类,每个Thread都会实例化一个 ThreadLocalMap 实例
set 方法如下:
// key 就是 经常用的 ThreadLocal 实例 ,value就是要设置的值
private void set(ThreadLocal<?> key, Object value);