@RequestHeader 获取不到 过滤器中添加请求头

问题遇到的现象和发生背景

目前,我在项目中;通过过滤器加上了请求头;但是利用 @RequestHeader 注解获取不到这个参数;通过 HttpServletRequest 却可以获得;不清楚原因;下面是代码;

用代码块功能插入代码,请勿粘贴截图

public class CustomRequestWrapper extends HttpServletRequestWrapper {

    private final Map<String, String> headers = new HashMap<>();


    public CustomRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    public void addHeader(String key, String val) {
        headers.put(key, val);
    }

    @Override
    public String getHeader(String name) {
        return headers.get(name);
    }
}
HttpServletRequest request = (HttpServletRequest) servletRequest;
CustomRequestWrapper requestWrapper = new CustomRequestWrapper(request);
requestWrapper.addHeader("id", "-1");
System.out.println(request.getHeader("id"));//可以获得
@RequestHeader("id") 不可以;
运行结果及报错内容

Required request header 'id' for method parameter type String is not present

你需要有个filter,将默认的request替换为你wrapper后的,类似这样的,
chain.doFilter(cachedRequestHttpServletRequest, servletResponse);

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.util.*;

/**
 * @author TheGeekyAsian
 * Created at 2:22 PM, 2/18/20
 *
 * See <a href="http://thegeekyasian.com">TheGeekyAsian.com</a>
 * @see <a href="http://github.com/thegeekyasian/">TheGeekyAsian on GitHub</a>
 */

@Component
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class HttpRequestLoggingFilter implements Filter {

    /* Just to avoid logging credentials or related details. You can empty this list or remove it completely if you
    want to log the security details too. */
    private static final List<String> HEADERS_TO_SKIP = Arrays.asList("authorization", "token", "security", "oauth", "auth");

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        CachedRequestHttpServletRequest cachedRequestHttpServletRequest =
                new CachedRequestHttpServletRequest((HttpServletRequest) servletRequest);
        String log = String.format("URL: %s | Requester: %s | HTTP Method: %s | Headers: %s | QueryStringParams: %s | RequestBody: %s",
                cachedRequestHttpServletRequest.getRequestURL(), cachedRequestHttpServletRequest.getRemoteAddr(),
                cachedRequestHttpServletRequest.getMethod(), getRequestHeaders(cachedRequestHttpServletRequest),
                cachedRequestHttpServletRequest.getQueryString(), getBody(cachedRequestHttpServletRequest));

        // Log your request here!
        System.out.println(log); //Try using a logger instead of the print statement.

        chain.doFilter(cachedRequestHttpServletRequest, servletResponse);
    }

    private Map<String, String> getRequestHeaders(HttpServletRequest request) {
        Map<String, String> headersMap = new HashMap<>();
        Enumeration<String> headerEnumeration = request.getHeaderNames();
        while (headerEnumeration.hasMoreElements()) {
            String header = headerEnumeration.nextElement();

            // Filter the headers that you need to skip.
            // If you don't want to filter any headers and want to log all of them,
            // you can remove the condition below.
            if (HEADERS_TO_SKIP.stream().noneMatch(h -> h.toLowerCase().contains(header.toLowerCase())
                    || header.toLowerCase().contains(h.toLowerCase()))) {
                headersMap.put(header, request.getHeader(header));
            }
        }
        return headersMap;
    }

    private String getBody(CachedRequestHttpServletRequest request) throws IOException {
        StringBuilder body = new StringBuilder();
        String line;
        BufferedReader reader = request.getReader();
        while ((line = reader.readLine()) != null) {
            body.append(line);
        }
        return body.toString();
    }

    private static class CachedRequestHttpServletRequest extends HttpServletRequestWrapper {

        private byte[] cachedBody;

        public CachedRequestHttpServletRequest(HttpServletRequest request) throws IOException {
            super(request);
            this.cachedBody = StreamUtils.copyToByteArray(request.getInputStream());
        }

        @Override
        public ServletInputStream getInputStream() {
            return new CachedRequestServletInputStream(this.cachedBody);
        }

        @Override
        public BufferedReader getReader() {
            return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(this.cachedBody)));
        }
    }

    private static class CachedRequestServletInputStream extends ServletInputStream {

        private InputStream cachedBodyInputStream;

        public CachedRequestServletInputStream(byte[] cachedBody) {
            this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);
        }

        @Override
        public boolean isFinished() {
            try {
                return cachedBodyInputStream.available() == 0;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener readListener) {
            throw new UnsupportedOperationException();
        }

        @Override
        public int read() throws IOException {
            return cachedBodyInputStream.read();
        }
    }
}
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^