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