Spring Boot 请求头返回空值

Posted

技术标签:

【中文标题】Spring Boot 请求头返回空值【英文标题】:Spring Boot request header return null value 【发布时间】:2019-07-22 05:52:12 【问题描述】:

我有一个 Spring Boot 项目,其中包含一些 Rest API。我有两个分别名为 request_datetenant 的自定义标头。

我试图在拦截器中读取这些标头的值,但它仅读取 tenant 的值,并为 request_date 返回 null。

重要

我使用过滤器来包装请求对象,因为我想稍后再读取请求正文。 有一个过滤器可以添加 CORS 标头。

当我在 localhost 上运行我的项目并调试代码时,我能够成功读取两个标头的值。

但是,当我在生产中部署我的应用程序并使用邮递员或其他客户端发出请求时,request_date 标头的值始终被读取为 null。

我不确定这似乎是什么问题。我正在使用 Spring boot v1.5.10.RELEASEJDK 1.8

注意:

我尝试将标题重命名为 input_date 之类的名称。但是,它仍然显示为 null。

以下是相关代码

TestInterceptor

public class TestInterceptor extends HandlerInterceptorAdapter 

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 

        String requestDate = request.getHeader("request_date");
        String tenant = request.getHeader("Tenant");

        /*Perform some checks*/

        return super.preHandle(request, response, handler);
    


CorsFilter

public class ApiCorsFilter extends OncePerRequestFilter 

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException 
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers," +
                " X-Requested-With, Origin, X-Auth-Token, Tenant, request_date");
        response.addHeader("Access-Control-Expose-Headers", "X-Auth-Token, Content-Disposition");
        chain.doFilter(request, response);
    


RequestCacheFilter

public class RequestCacheFilter extends OncePerRequestFilter 

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException 

        HttpServletRequest req = new RequestWrapper(request);
        String body = ((RequestWrapper) req).getBody();

        /*Do some operation*/

        filterChain.doFilter(req, response);
    

【问题讨论】:

如果你打电话给request.getHeaderNames()怎么办?是否有可能在缺少的标头中设置了 null? 我没有调用 request.getHeaderNames(),但我可以读取其他标头的值。该问题仅特定于“request_date”标头 【参考方案1】:

某些网络工具可以删除名称中包含下划线的标头。根据this answer,下划线是一个合法字符,但并不常见,有时工具需要额外的配置来支持它。

将您的标题重命名为requestDaterequest-date,看看是否有帮助。如果它在没有下划线的情况下工作,而不是检查客户端和服务器之间的网络路由,例如也许有一个代理可以丢弃它们?

【讨论】:

【参考方案2】:

问题出在 nginx 配置上。

我为服务器设置了 underscores_in_headers on;,现在它不会删除名称中带有下划线的标题。

@Karol Dowbecki 建议的解决方案也可以。当我将标题重命名为 requestDate 时,我能够成功读取该值。

【讨论】:

以上是关于Spring Boot 请求头返回空值的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2从入门到入坟 | 请求参数处理篇:常用参数注解之@RequestHeader

Spring Boot 2从入门到入坟 | 请求参数处理篇:常用参数注解之@RequestHeader

Spring Boot异常处理

Spring boot 错误处理机制

在 Spring Boot 中设置响应头

spring重定向设置请求头header