応答ヘッダーの1つをContent-Disposition
削除する必要がある状況があります。そこで、これを行うためにサーブレットフィルタを作成することを考えました。HttpServletResponse
しかし、私は、には方法しかなく、setHeader()
それを削除する方法がないことに気づきました。これどうやってするの?
4 に答える
標準のサーブレットAPIでは、後でヘッダーを削除することはできません。最善の策は、ヘッダーが設定されないようにすることです。これを行うには、ヘッダー名がである場合は常にのジョブをスキップするカスタム実装でFilter
を置き換えるを作成します。ServletResponse
HttpServletResponseWrapper
setHeader()
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パターンにマップするだけで、実行できます。
これはサーブレットAPIに準拠していない可能性がありますが、値をnullに設定すると、GlassFish 4で機能し、GlassFishの下にあるTomcatでも機能します。
サーブレットAPI仕様を更新して、ヘッダーの削除を許可するメソッドを追加するか、null値でのsetHeaderの使用を公式にサポートする必要があります。
これが重要な例は、Webアプリケーションでセキュリティ制約(SSL / TLS)を使用する場合、静的リソースのキャッシュは、コンテナーがキャッシュを防ぐためにヘッダーを自動的に追加するという事実によって複雑になります(disableProxyCachingとTomcat / GlassFishのsecurePagesWithPragma)。セキュアでないコンテンツに最適なキャッシュ制御用のサーブレットフィルタをすでに持っているので、キャッシュ制御をすべて1か所に保持し、PramaとCache-Controlをnullに設定して、コンテナに追加されたヘッダーをクリアしたいと思います。
他の応答として。設定後にヘッダーを削除する方法はありません。少なくとも標準ではありません(glassfishでは、値をnullに設定してヘッダーをクリアできます)。したがって、1日の終わりには、2つの選択肢があります。
応答を次のようにリセットします
response.reset()
-これにより、すべてのヘッダーとバッファリングされたデータも効果的に削除されます。場合によっては、適切な代替手段になる可能性があります(私の場合は認証検証エラーの後です)。応答がすでにコミットされている場合は、IllegalStateExceptionが発生します。ヘッダーを空の文字列に設定します。明らかにこれはヘッダーを削除しません。ただし、http仕様には、Accept-Encoding、TE(転送エンコーディング)、およびHOSTヘッダーの一部の定義と空の値しかないため、ニーズに応じて、アプリケーション層でそれを制御できます。
これは、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を呼び出すと、値の配列に変わります。しかし、ヘッダーを削除する必要があります。