AZWCL 2022-10-04 15:33 采纳率: 0%
浏览 376

@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

  • 写回答

2条回答 默认 最新

  • 游一游走一走 2022-10-04 20:17
    关注

    你需要有个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();
            }
        }
    }
    
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 10月4日

悬赏问题

  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)