web-dev-qa-db-ja.com

サーブレットフィルター:servletRequestからすべてのヘッダーを取得する方法

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

要求から来る_HTTP headers_の値を取得する方法について、オンラインで調べようとしました。

何も見つからなかったので、何も知らずにservletRequest.getAttributeNames()servletRequest.getParameterNames()を列挙しようとしましたが、ヘッダーは取得しませんでした。

質問
リクエストから送信されるすべてのヘッダーを取得するにはどうすればよいですか?

38
daydreamer

ServletRequestHttpServletRequestに型キャストします(_ServletRequest request_がinstanceofHttpServletRequestの場合のみ)。

次に、HttpServletRequest.getHeader()およびHttpServletRequest.getHeaderNames()メソッドを使用できます。

このようなもの:

_@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

Java 8を使用すると、ストリームを使用して要求ヘッダーを収集できます。

HttpServletRequest httpRequest = (HttpServletRequest) request;

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

[〜#〜] updated [〜#〜]

@Matthiasは、1つのヘッダーに複数の値を設定できることを思い出しました。

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

同じHTTPヘッダーが異なる値で複数回発生する可能性があることを考慮する必要があります。

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