3

ページの内容に基づいてこのヘッダーを変更する必要があります。

例:これは考案された例です-要求されたためです。特定のヘッダーの詳細に入ることができませんサーブレット/ページは、アクセスされたバックエンドシステムに基づいてヘッダーspecialheader=xyzを設定します。このspecialheaderが設定されている場合、フィルターはそれをxyz+abcに変更します。ヘッダーが設定されていない場合、フィルターはヘッダーを123に設定します。

フィルタを使用して、ラップを作成し、HttpServletResponse戻る途中で変更することができます。しかし、私は細部に曖昧です。

フィルタが機能する前に、出力がクライアントに返送されないようにする必要があることはわかっています。これを行うには、自分でそれを渡しOutputStream、出力をバッファリングする必要がありますか?

私は本当にそれをする必要がありますか?サーバーに負荷をかける可能性のある出力のバッファリングを回避できますか?

基本的な質問は、doFilter呼び出しの後にヘッダーを変更する必要がある場合、最低限必要なことは何ですか?フラッシュを過剰に使用するなど、出力がコミットされないようにする他の方法はありますか?

4

3 に答える 3

1

getHeaderとgetHeaderNamesを実装して、破棄するヘッダーを無視し、ラッパーをフィルターとして設定するだけです。

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.Collection;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class GenericResponseWrapper extends HttpServletResponseWrapper {



    public GenericResponseWrapper(final HttpServletResponse response) {
        super(response);    
    }

    @Override
    public String getHeader(String name) {
        // TODO Auto-generated method stub
        return super.getHeader(name);
    }
    @Override
    public Collection<String> getHeaderNames() {
        // TODO Auto-generated method stub
        return super.getHeaderNames();
    }
}


public class Wrapper implements Filter {

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest httpRequest = (HttpServletRequest) request;
        final HttpServletResponse httpResponse = (HttpServletResponse) response;
            final GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse);
            wrapper.getResponse().setCharacterEncoding("UTF-8");

            chain.doFilter(request, wrapper);
}
}
于 2012-11-06T18:45:36.827 に答える
1

「すでに設定されているサーブレット応答のヘッダーを変更する方法」を検索するたびに、この投稿が最初に表示されます。質問の説明が異なっていても、(おそらく他の多くのように)サーブレット応答のヘッダーを変更する方法を知りたいです。すでに設定されています。この点で、私は(質問/回答を書く代わりに)探している人のために私の答えを投稿したいと思います。

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して、同じ値を持つ2つのヘッダーがあり、2番目のヘッダーは前のヘッダーを上書きするか、**応答にすでに存在するヘッダーを変更します**。

Set-Cookie: locale=EN; Path=/; HttpOnly;
Set-Cookie: locale=EN; Path=/; SameSite=None; Secure; HttpOnly;

参考:Tomcat 7.0.104、サーブレット3.1およびSpring 4.2.x

于 2020-09-09T06:48:52.623 に答える
-1

HttpServletRequestWrapperのgetHeaderメソッドをオーバーライドすることで、以下のようなことができます。

@Override
public Enumeration<String> getHeaders(String name) {
    List<String> values = Collections.list(super.getHeaders(name));
    if (headerMap.containsKey(name)) {
        if (name.equals("Header_attibutes_needs_to_be_replace")) {
            values.clear();
        }
        values.add(headerMap.get(name));
    }
    return Collections.enumeration(values);
}

そして、フィルター内で、新しい値を設定します

 wrappedRequest = new HeaderMapRequestWrapper(request);
 wrappedRequest.addHeader("Header_attibutes_needs_to_be_replace", value);
于 2022-03-03T06:07:08.560 に答える