web-dev-qa-db-fra.com

Filtre de servlet: Comment obtenir tous les en-têtes de servletRequest?

Voici à quoi ressemble mon WebFilter

@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() {
    }
}

J'ai essayé de trouver en ligne comment obtenir des valeurs pour HTTP headers À partir d'une requête.

Je n'ai rien trouvé, j'ai donc essayé d'énumérer sur servletRequest.getAttributeNames() et servletRequest.getParameterNames() sans rien savoir, mais je n'ai aucun en-tête.

Question
Comment puis-je obtenir tous les en-têtes provenant de la demande?

38
daydreamer

Typecast ServletRequest dans HttpServletRequest (seulement si ServletRequest request Est un instanceofHttpServletRequest).

Ensuite, vous pouvez utiliser la méthode HttpServletRequest.getHeader() et HttpServletRequest.getHeaderNames().

Quelque chose comme ça:

@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);
}
72
Buhake Sindi

Avec Java 8, vous pouvez utiliser un flux pour collecter les en-têtes de requête:

HttpServletRequest httpRequest = (HttpServletRequest) request;

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

[~ # ~] mis à jour [~ # ~]

@ Matthias m'a rappelé la possibilité d'avoir plusieurs valeurs pour un en-tête:

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))
    ));

HttpHeaders

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

https://Gist.github.com/Cepr0/fd5d9459f17da13b29126cf313328fe

26
Cepr0

Vous devez considérer que le même en-tête HTTP peut se produire plusieurs fois avec des valeurs différentes:

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;
}));
1
Matthias