Springboot3.2.0使用RequestContextHolder获取HttpServletRequest为NULL

在之前的版本中一般为了能在任意地方都能获取到HttpServletRequest我们一般都会自己封装工具类从RequestContextHolder中获取到

public static HttpServletRequest getRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert servletRequestAttributes != null;
        return servletRequestAttributes.getRequest();
    }

但是在新版的SpringBoot3.2.0版本中这种方式获取到的ServletRequestAttributes是null,点击进去RequestContextHolder查看源代码发现少了依赖

Springboot3.2.0使用RequestContextHolder获取HttpServletRequest为NULL_第1张图片

即使我在pom中加入的响应的依赖也还是不行。(可能是我使用方式不对,如果大家有更好的解决方案可以留言我学习学习,谢谢。)

解决方案

实现思路大概就是:自定义一个RequestHolder,然后在过滤器中将HttpServletRequest和HttpServletResponse设置到我们自定义的Holder中

自定义MyRequestHolder

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 自定义请求上下文
 *
 * @author: 张定辉
 * @date: 2023/12/17 15:56
 * @description: 自定义请求上下文
 */
public class MyRequestHolder {
    private  MyRequestHolder(){}

    private static final ThreadLocal<HttpServletRequest> request=new ThreadLocal<>();

    private static final ThreadLocal<HttpServletResponse> response=new ThreadLocal<>();


    public static void setRequest(HttpServletRequest httpServletRequest){
        request.set(httpServletRequest);
    }

    public static void setResponse(HttpServletResponse httpServletResponse){
        response.set(httpServletResponse);
    }

    public static void remove(){
        request.remove();
        response.remove();
    }

    public static HttpServletRequest getRequest(){
        return request.get();
    }

    public static HttpServletResponse getResponse(){
        return response.get();
    }
}
过滤器中设置
/**
 * @author: 张定辉
 * @date: 2023/12/17 11:00
 * @description: 请求体封装拦截器
 */
public class RequestWrapperFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        RequestWrapper requestWrapper=new RequestWrapper(request);
        MyRequestHolder.setRequest(requestWrapper);
        MyRequestHolder.setResponse(response);
        filterChain.doFilter(requestWrapper,response);
        //最后调用remove清除ThreadLocal中的值避免内存泄露
        MyRequestHolder.remove();
    }
}

由于我这里是使用SpringSecurity作为权限验证的,所以我的过滤器也是使用的Security的,最后把这个过滤器加入到Security的过滤器链中即可。如果没使用Security的话则自定义过滤器了添加即可

最终使用
public static HttpServletRequest getRequest() {
        return MyRequestHolder.getRequest();
}

你可能感兴趣的:(踩坑日记,spring,boot)