You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat内嵌JSP中图片Cache-Control异常问题求助

问题分析与解决方案

环境信息

Environment :         
    java : oracle 8
    Spring4 xml config
    eclipse version: 2020-06(4.16.0)
    was-server: tomcat 8.5
    servlet: web-app_3_1.xsd version=3.1 
    jsp: 2.1

问题现象

  • 首页landing.jsp中的图片aaa响应头Cache-Control为max-age=0,符合预期
  • 内嵌JSP /WEB-INF/jsp/usr/common/curation.jsp中的图片响应头始终是no-cache, no-store, must-revalidate,导致每次都从Tomcat重新下载
  • 未主动设置过缓存头,Tomcat自动应用该策略
  • 自定义Filter尝试覆盖缓存头,但未生效

为什么Filter没生效

你当前的Filter是在chain.doFilter(request, response)之后设置Cache-Control头,此时响应可能已经被提交(committed)——比如内嵌JSP或处理图片的Servlet已经输出了内容并刷新了响应,这时候再修改响应头会被Tomcat忽略,无法生效。

解决方案

方案1:调整Filter逻辑,强制覆盖响应头

修改Filter,使用HttpServletResponseWrapper拦截所有响应头设置操作,确保Cache-Control最终被设置为max-age=0:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{
    HttpServletResponse resp = (HttpServletResponse) response;
    
    HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(resp) {
        @Override
        public void setHeader(String name, String value) {
            if ("Cache-Control".equalsIgnoreCase(name)) {
                super.setHeader(name, "max-age=0");
            } else {
                super.setHeader(name, value);
            }
        }

        @Override
        public void addHeader(String name, String value) {
            if ("Cache-Control".equalsIgnoreCase(name)) {
                super.setHeader(name, "max-age=0");
            } else {
                super.addHeader(name, value);
            }
        }
    };
    
    chain.doFilter(request, wrapper);
}

方案2:修改Tomcat静态资源缓存配置

如果这些图片是静态资源(如放在webapp/images目录下),Tomcat的DefaultServlet默认会对静态资源设置缓存策略。可以在项目的web.xml中覆盖全局配置:

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>cacheControl</param-name>
        <param-value>max-age=0</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

方案3:检查动态资源的缓存头设置

如果内嵌JSP中的图片是通过动态Servlet/JSP/控制器生成的(比如通过Spring MVC输出图片流),需要找到对应的处理代码,检查是否主动设置了no-cache头。例如:

// 找到类似代码并修改
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
// 替换为
response.setHeader("Cache-Control", "max-age=0");

方案4:调整Filter的映射顺序

如果项目中有其他Filter(如编码Filter、安全Filter),可能先于你的testFilter执行并修改了响应头。需要确保你的Filter在web.xml中最先被映射:

<!-- 确保testFilter是第一个filter-mapping -->
<filter-mapping>
    <filter-name>testFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 其他Filter映射放在后面 -->
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

验证方法

修改后重启Tomcat,打开Chrome开发者工具的网络面板,刷新页面,查看对应图片的响应头,确认Cache-Control是否变为max-age=0。

内容的提问来源于stack exchange,提问作者jijonbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:17:35