每当我搜索“如何修改已设置的 servlet 响应中的标头”时,这篇文章首先出现,即使问题描述不同,我(可能像许多其他人一样)想知道如何修改 servlet 响应中的标头已经设置好了。在这方面,我想为正在寻找的人发布我的答案(而不是写一个问题/答案)。
public class SameSiteCookieHeaderFilter implements Filter {
private static final String LOCALE_ID_COOKIE = "locale";
private static final String SET_COOKIE_HEADER = "Set-Cookie";
@Override
public void destroy() {
}
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
final HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
final Collection<String> setCookieHeaders = httpServletResponse.getHeaders(SET_COOKIE_HEADER);
for (final String setCookieHeader : setCookieHeaders) {
httpServletResponse.addHeader(SET_COOKIE_HEADER, setCookieHeader + "; Secure; SameSite=None");
}
if (setCookieHeaders.size() == 0) {
final Cookie[] cookies = httpServletRequest.getCookies();
for (final Cookie cookie : cookies) {
if (cookie.getName().equals(LOCALE_ID_COOKIE)) {
httpServletResponse.addHeader(SET_COOKIE_HEADER, buildSessionIdCookie(cookie.getValue()));
}
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
private String buildSessionIdCookie(final String value) {
return LOCALE_ID_COOKIE + "=" + value + "; " + "Path=/; " + "SameSite=None; " + "Secure; HttpOnly;";
}
web.xml
<filter>
<filter-name>SameSiteCookieHeaderFilter</filter-name>
<filter-class>de.chemmedia.kw.core.filter.SameSiteCookieHeaderFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SameSiteCookieHeaderFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
所以它的作用是检测Set-Cookie
标头并添加属性,或者在每个响应中获取SameSite=None
Cookie 和构造。这样,就会有两个具有相同值的标头,第二个将覆盖前一个,**或修改响应中已经存在的标头**。Set-Cookie
SameSite=None
Set-Cookie
Set-Cookie: locale=EN; Path=/; HttpOnly;
Set-Cookie: locale=EN; Path=/; SameSite=None; Secure; HttpOnly;
仅供参考:tomcat 7.0.104、Servlet 3.1 和 Spring 4.2.x