Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot request header return null value

I have a spring boot project which has some Rest APIs in it. I have two custom headers named request_date and tenant respectively.

I am trying to read the value of these headers in an interceptor, but it reads the value for only tenant and returns null for request_date.

Important

  • I use a filter to wrap the request object because I want to read the request body later.
  • There is a filter to add CORS headers.

When I run my project on localhost and debug the code, I am successfully able to read both the headers' values.

However, when I deploy my application in production and make the request using postman or some other client, the request_date header's value is always read as null.

I am not sure what seems to be the problem with this. I am using Spring boot v1.5.10.RELEASE and JDK 1.8

Note:

  • I have tried to rename the header to something like input_date. However, it still reads null.

The following is the relevant code

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);
    }
}
like image 215
greenPadawan Avatar asked Feb 28 '19 10:02

greenPadawan


People also ask

What is @requestparam in Spring Boot?

1. Overview In this quick tutorial, we’ll explore Spring's @RequestParam annotation and its attributes. Simply put, we can use @RequestParam to extract query parameters, form parameters, and even files from the request.

What is httpheaders in Spring Boot?

HttpHeaders is Spring specific type which implements MultiValueMap<String,String> and defines all convenience methods like getContentType (), getCacheControl () etc. If target method parameter is not String, automatic type conversion can happen. All simple types such as int, long, Date, etc. are supported by default.

How to specify HTTP request header name using @requestheader annotation?

@RequestHeader element 'value' is used to specify HTTP request header name: Just like @PathVariable and @RequestParam, 'value' element of @RequestHeader annotation can be skipped if type variable name is same as header name.

How to bind HTTP request header attributes to controller parameters?

The @RequestHeader annotation is used to bind HTTP request header attributes values to controller method parameters. @RequestHeader element 'value' is used to specify HTTP request header name:


2 Answers

The issue was with the nginx configuration.

I set the underscores_in_headers on; for the server and now it doesn't drop the headers with underscore in their names.

The solution suggested by @Karol Dowbecki works as well. When I renamed my header to requestDate, I was able to read the value successfully.

like image 133
greenPadawan Avatar answered Sep 29 '22 13:09

greenPadawan


Some network tools can drop headers that contain underscore in it's name. As per this answer underscore is a legal character but it's uncommon and sometimes tools require additional configuration to support it.

Rename your header to requestDate or request-date and see if it helps. If it works without underscore than inspect network route between client and server e.g. maybe there is a proxy that drops them?

like image 43
Karol Dowbecki Avatar answered Sep 29 '22 14:09

Karol Dowbecki