35

応答ヘッダーの1つをContent-Disposition削除する必要がある状況があります。そこで、これを行うためにサーブレットフィルタを作成することを考えました。HttpServletResponseしかし、私は、には方法しかなく、setHeader()それを削除する方法がないことに気づきました。これどうやってするの?

4

4 に答える 4

57

標準のサーブレットAPIでは、後でヘッダーを削除することはできません。最善の策は、ヘッダーが設定されないようにすることです。これを行うには、ヘッダー名がである場合は常にのジョブをスキップするカスタム実装でFilterを置き換えるを作成します。ServletResponseHttpServletResponseWrappersetHeader()Content-Disposition

基本的に:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
        public void setHeader(String name, String value) {
            if (!name.equalsIgnoreCase("Content-Disposition")) {
                super.setHeader(name, value);
            }
        }
    });
}

そのフィルターを目的のURLパターンにマップするだけで、実行できます。

于 2011-10-25T20:14:35.517 に答える
4

これはサーブレットAPIに準拠していない可能性がありますが、値をnullに設定すると、GlassFish 4で機能し、GlassFishの下にあるTomcatでも機能します。

サーブレットAPI仕様を更新して、ヘッダーの削除を許可するメソッドを追加するか、null値でのsetHeaderの使用を公式にサポートする必要があります。

これが重要な例は、Webアプリケーションでセキュリティ制約(SSL / TLS)を使用する場合、静的リソースのキャッシュは、コンテナーがキャッシュを防ぐためにヘッダーを自動的に追加するという事実によって複雑になります(disableProxyCachingとTomcat / GlassFishのsecurePagesWithPragma)。セキュアでないコンテンツに最適なキャッシュ制御用のサーブレットフィルタをすでに持っているので、キャッシュ制御をすべて1か所に保持し、PramaとCache-Controlをnullに設定して、コンテナに追加されたヘッダーをクリアしたいと思います。

于 2014-10-16T17:59:56.113 に答える
2

他の応答として。設定後にヘッダーを削除する方法はありません。少なくとも標準ではありません(glassfishでは、値をnullに設定してヘッダーをクリアできます)。したがって、1日の終わりには、2つの選択肢があります。

  1. 応答を次のようにリセットしますresponse.reset()-これにより、すべてのヘッダーとバッファリングされたデータも効果的に削除されます。場合によっては、適切な代替手段になる可能性があります(私の場合は認証検証エラーの後です)。応答がすでにコミットされている場合は、IllegalStateExceptionが発生します。

  2. ヘッダーを空の文字列に設定します。明らかにこれはヘッダーを削除しません。ただし、http仕様には、Accept-Encoding、TE(転送エンコーディング)、およびHOSTヘッダーの一部の定義と空の値しかないため、ニーズに応じて、アプリケーション層でそれを制御できます。

于 2016-04-07T16:57:23.197 に答える
1

これは、Spring4を使用している場合は機能しません。Expires応答ヘッダーを削除しようとしています。すべてのページに対して。そのようです:

public class CachingFilter implements Filter {
    private final Log logger = LogFactory.getLog(getClass());

    public CachingFilter() {}
    public void destroy() {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        logger.debug("doFilter()");
        chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
            public void setHeader(String name, String value) {
                logger.debug("setHeader(" + name + ","+value+")");

                if (!name.equalsIgnoreCase("Expires")) {
                    super.setHeader(name, value);
                }
            }
        });
    }

    public void init(FilterConfig fConfig) throws ServletException {}
}

そして、これが私がフィルターを追加する方法です:

public class AppConfig implements WebApplicationInitializer {
    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppContext.class);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);

        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);

        FilterRegistration.Dynamic noCache = servletContext.addFilter("noCacheFilter", new CachingFilter());
        noCache.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

        servletContext.addListener(new ContextLoaderListener(rootContext));
    }
}

ExpiresおよびCache-Controlに対してsetHeader()が呼び出されていますが、Expiresフィルター値またはCache-Control値をオーバーライドできません。Cache-Control値に追加できます。Cache-ControlでsetHeaderを呼び出すと、値の配列に変わります。しかし、ヘッダーを削除する必要があります。

于 2016-02-25T06:00:20.850 に答える