95

Here is how my WebFilter looks like

@WebFilter("/rest/*")
public class AuthTokenValidatorFilter implements Filter {

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

    @Override
    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
        final Enumeration<String> attributeNames = servletRequest.getAttributeNames();
        while (attributeNames.hasMoreElements()) {
            System.out.println("{attribute} " + servletRequest.getParameter(attributeNames.nextElement()));
        }

        final Enumeration<String> parameterNames = servletRequest.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            System.out.println("{parameter} " + servletRequest.getParameter(parameterNames.nextElement()));
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
    }
}

I tried to find out online as to how to get values for HTTP headers coming from request.

I did not find anything, so I tried to enumerate on servletRequest.getAttributeNames() and servletRequest.getParameterNames() without knowing anything, but I do not get any headers.

Question
How can I get all the headers coming from the request?

daydreamer
  • 87,243
  • 191
  • 450
  • 722

4 Answers4

123

Typecast ServletRequest into HttpServletRequest (only if ServletRequest request is an instanceof HttpServletRequest).

Then you can use HttpServletRequest.getHeader() and HttpServletRequest.getHeaderNames() method.

Something like this:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    Enumeration<String> headerNames = httpRequest.getHeaderNames();

    if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                    System.out.println("Header: " + httpRequest.getHeader(headerNames.nextElement()));
            }
    }

    //doFilter
    chain.doFilter(httpRequest, response);
}
chengbo
  • 5,789
  • 4
  • 27
  • 41
Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
  • @BuhakeSindi are there indicators under what circumstances `ServletRequest` might be sth. different than an `HttpServletRequest`? – sthzg Oct 17 '15 at 12:41
  • 1
    'HttpServletReqiest' IS A 'ServletRequest'. It is a sub-interface of. ServletRequest. There can be various classes/interfaces of ServletRequest such as 'PortletRequest' hence its always to do an 'instanceof' check for various servlet types. – Buhake Sindi Oct 17 '15 at 16:32
  • Why getHeaderNames(); missed some header like x-forward-for, keep-alive detail etc? – Asif Mushtaq Aug 26 '16 at 20:06
  • 1
    @UnKnown those headers are populated by the proxy servers. It has to be configured on server level. The Servlet just returns the parameters set by those servers. – Buhake Sindi Feb 21 '17 at 06:23
80

With Java 8+ you can use a stream to collect request headers:

HttpServletRequest httpRequest = (HttpServletRequest) request;

Map<String, String> headers = Collections.list(httpRequest.getHeaderNames())
    .stream()
    .collect(Collectors.toMap(h -> h, httpRequest::getHeader));

UPDATED

@Matthias reminded me that headers can have multiple values:

Map<String, List<String>>

Map<String, List<String>> headersMap = Collections.list(httpRequest.getHeaderNames())    
    .stream()
    .collect(Collectors.toMap(
        Function.identity(), 
        h -> Collections.list(httpRequest.getHeaders(h))
    ));

org.springframework.http.HttpHeaders

HttpHeaders httpHeaders = Collections.list(httpRequest.getHeaderNames())
    .stream()
    .collect(Collectors.toMap(
        Function.identity(),
        h -> Collections.list(httpRequest.getHeaders(h)),
        (oldValue, newValue) -> newValue,
        HttpHeaders::new
    ));

https://gist.github.com/Cepr0/fd5d9459f17da13b29126cf313328fe3

Cepr0
  • 28,144
  • 8
  • 75
  • 101
  • 1
    did you try to compile this? – Eugene Feb 13 '19 at 03:00
  • I had to tweak it slightly for Spring - ```response.getHeaderNames() .stream() .collect(Collectors.toMap( Function.identity(), h -> new ArrayList<>(response.getHeaders(h)), (oldValue, newValue) -> newValue, HttpHeaders::new ));``` – bobmarksie Oct 21 '19 at 16:30
  • @bobmarksie in your variant you are using `response`, but the question was about `request`. Unfortunately `HttpServletRequest#getHeaderNames` returns `Enumeration`, not `Collection`. – Cepr0 Oct 21 '19 at 17:11
  • Thanks @Cepr0! Still found your answer very useful, even though I was using it in a different way. – bobmarksie Oct 22 '19 at 08:51
  • Especially gist url is useful to test and gets clarified all doubts. – Paramesh Korrakuti Feb 24 '22 at 09:28
5

You should consider that the same HTTP header can occur multiple times with different values:

Map<String, Serializable> headers = Collections.list(request.getHeaderNames()).stream().collect(Collectors.toMap(h -> h, h -> {
    ArrayList<String> headerValues = Collections.list(request.getHeaders(h));
    return headerValues.size() == 1 ? headerValues.get(0) : headerValues;
}));
Matthias
  • 7,432
  • 6
  • 55
  • 88
1

In a spring boot application, this works inside any method (with Java 8)

    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import javax.servlet.http.HttpServletRequest;
    import java.util.Collections;
    
...
...

    public void anyMethod(){
        HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        Collections.list(req.getHeaderNames()).stream().forEach(System.out::println);
    }
smilyface
  • 5,021
  • 8
  • 41
  • 57