我遇到这样一种情况,需要删除其中一个响应头Content-Disposition
,所以我想编写一个Servlet过滤器来实现。但是我发现HttpServletResponse
只有一个setHeader()
方法而没有删除该头的方法。
我该怎么做?
我遇到这样一种情况,需要删除其中一个响应头Content-Disposition
,所以我想编写一个Servlet过滤器来实现。但是我发现HttpServletResponse
只有一个setHeader()
方法而没有删除该头的方法。
我该怎么做?
按照标准的Servlet API,您无法在之后删除请求头。您最好的选择是仅仅防止设置该请求头。您可以创建一个Filter
,它将ServletResponse
替换为自定义HttpServletResponseWrapper
实现,每当请求头名称为Content-Disposition
时跳过setHeader()
的任务。
基本上:
@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模式即可使其运行。
response.reset()
重置响应 - 这有效地删除了所有标题和任何缓冲数据,根据你的情况可能是一个好的选择(在我的情况下是在身份验证验证错误之后) 。如果响应已经提交,则会出现IllegalStateException。使用Spring 4对我无效。我正在尝试删除所有页面的过期响应头,就像这样:
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));
}
}
setHeader()被调用用于Expires和Cache-Control,但我无法覆盖Expires过滤器值或Cache-Control值。我可以添加到Cache-Control值。如果我在Cache-Control上调用setHeader,则会变成一个值数组。但我需要删除标题。
chain.doFilter()
后整个过程中Web应用程序设置的标头。它不控制在此之前或之后设置的标头。顺便说一下,这很有道理 :) - BalusCaddHeader(String name, String value)
方法。 - Milanka