Servlet Filter: 如何从 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()不知道任何东西,但我没有得到任何标题。

提问
我如何获得来自请求的所有头?

149344 次浏览

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

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

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

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