在 Spring Boot JAVA 中将自定义 headers 注入 ServletRequest

Injecting custom headers into ServletRequest in Spring Boot JAVA

我需要将自定义 headers 注入到 spring 启动应用程序收到的每个请求中,为此,我编写了一些代码,但它似乎没有发挥作用。简而言之,我已经实现了 Filter 接口并定义了 doFilter 方法,扩展了 HttpServletRequestWrapper class,并覆盖了 getHeader() 和 getHeaderNames() 方法以考虑到我正在阅读的自定义 headers属性文件。

但是,当我进入控制器并检查请求时,我没有获得通过 MyReqWrapper 设置的自定义 headers。下面是代码,我也尝试在 Whosebug 中搜索它,但找不到 is/could 错误的解决方案。有人能指出我正确的方向吗?

此外,请告诉我如何测试自定义 headers 是否实际设置。

这是过滤器实现

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ReqFilter implements Filter {
    private static final String CUSTOMHEADERENABLED = "customheadersenabled";
    private static final String CUSTOMHEADERCOUNT = "customheaderscount";
    
    @Autowired
    private Environment env;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        try {
            boolean customHeadersEnabled = Boolean.parseBoolean(env.getProperty(CUSTOMHEADERENABLED, "false"));
            int count = Integer.parseInt(env.getProperty(CUSTOMHEADERCOUNT, "0"));

            if (customHeadersEnabled && count > 0) {
                MyReqWrapper myReq = new MyReqWrapper((HttpServletRequest) servletRequest);
                myReq.processMyHeaders(count, env);
                filterChain.doFilter(customRequest, servletResponse);
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
        catch(ServletException ex){
            throw ex;
        }
    }

    @Override
    public void destroy() {
        //
    }
}

这是扩展 HttpServletRequestWrapper 的自定义请求包装器

final class MyReqWrapper extends HttpServletRequestWrapper {
    private static final String CUSTOMHEADERPREFIX = "header1";
    private final Map<String, String> myHeaders;

    public MyReqWrapper(HttpServletRequest request) {
        super(request);
        myHeaders = new HashMap<>();
    }

    @Override
    public String getHeader(String name) {
        String headerValue = myHeaders.get(name);

        if (headerValue != null){
            return headerValue;
        }
        return ((HttpServletRequest) getRequest()).getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        Set<String> set = new HashSet<>(myHeaders.keySet());

        Enumeration<String> headerNames = ((HttpServletRequest) getRequest()).getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String n = headerNames.nextElement();
            set.add(n);
        }
        return Collections.enumeration(set);
    }

    public void processMyHeaders(int headerCount, Environment env) {
        while(headerCount > 0){
            String [] headerKeyValue = Objects.requireNonNull(env.getProperty(String.format("%1$s%2$s", CUSTOMHEADERPREFIX, headerCount--)))
                    .split(":");
            this.myHeaders.put(headerKeyValue[0], headerKeyValue[1]);
        }
    }
}

我已经解决了这个问题,但我忘了用答案更新它。

所以问题是我在 ReqFilter 和控制器 classes 中使用来自两个不同命名空间的 HttpServletRequest class,即来自 "[=21] =].servlet4preview.http.HttpServletRequest" 和另一个来自 "javax.servlet.http.HttpServletRequest".

一旦我在两个文件中使用了统一命名空间,我就可以从控制器 classes 访问 headers。