【问题标题】:How to configure Spring to avoid setting Pragma No-Cache如何配置 Spring 以避免设置 Pragma No-Cache
【发布时间】:2012-02-17 01:54:00
【问题描述】:

我的系统是基于 Spring MVC 的,我检查了 Spring 是否自动设置 PRAGMA: no-cache。该系统通过 SSL 可供用户使用。当用户尝试使用 INTERNET EXPLORER 7 或 8 下载内容时,会出现 “Internet Explorer 无法从服务器下载文件” 之类的错误(更多详细信息:http://support.microsoft.com/default.aspx?scid=KB;EN-US;q316431&)。

我尝试像下面的代码一样配置 WebContentInterceptor 但不起作用:

<mvc:interceptors>
    <bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
        <property name="cacheSeconds" value="2100" />
        <property name="useExpiresHeader" value="false" />
        <property name="useCacheControlHeader" value="false" />
        <property name="useCacheControlNoStore" value="false" />
    </bean>
</mvc:interceptors>

如何避免 Spring 发送 Pragma: no-cache 并与 Cache Control 相关?

问候!

【问题讨论】:

  • 你注意到你链接的文章只适用于IE5和IE6吗?
  • 不,它适用于除 IE 9 之外的所有 IE。

标签: java spring jakarta-ee spring-mvc


【解决方案1】:

您可以编写自己的自定义拦截器并将标头值设置为响应对象。拦截器只不过是过滤器,所以覆盖过滤器并使用

prehandle 和 posthandle 分别设置请求和响应标头。

如果你想要具体的例子,请告诉我。

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <beans:bean id="customInterceptor"
            class="org.example.interceptors.CustomInterceptor">
        </beans:bean>
    </mvc:interceptor>

</mvc:interceptors>




 public class CustomInterceptor implements HandlerInterceptor{

     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView modelAndView) throws Exception {
     response.setHeader(...);}
}

【讨论】:

  • 嗨阿比!问题是 WebContentGenerator 类根据属性值 cacheSeconds 创建 HTTP 标头(如果为 -1,则没有标头,否则设置标头)。而且,在它们被设置之后,不可能从响应中删除它们......
  • 改用 HandlerInterceptor 并在 posthandle 中设置响应。
  • 嗨@Abhi!我按照你的建议做了,我在 preHandle 方法中实现了解决方案,它有效!这不是一个很好和明确的解决方案,但无论如何都能解决我的问题。 postHandle 方法无法解决,因为 HTTP 标头在执行时已经创建。
【解决方案2】:

最简单的方法可能只是阻止使用 servlet 过滤器编写标头。这样就无需修改 Spring 配置,并且您可以免费获得正确的缓存功能。

public class PragmaFilter implements Filter {

    private static String PRAGMA_HEADER = "Pragma";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(request, new NoPragmaHttpServletResponseWrapper(response));
    }

    @Override
    public void destroy() { }

    private final class NoPragmaHttpServletResponseWrapper extends HttpServletResponseWrapper {

        private NoPragmaHttpServletResponseWrapper(ServletResponse response) {
            super((HttpServletResponse) response);
        }

        @Override
        public void addHeader(String name, String value) {
            if (PRAGMA_HEADER.equals(name)) {
                return;
            }
            super.addHeader(name, value);
        }

        @Override
        public void setHeader(String name, String value) {
            if (PRAGMA_HEADER.equals(name)) {
                return;
            }
            super.setHeader(name, value);
        }
    }

}

【讨论】:

    【解决方案3】:

    尝试将缓存秒数设置为负值。


    如果这没有帮助,您将需要覆盖:

       protected final void preventCaching(HttpServletResponse response)
    

      protected final void applyCacheSeconds(HttpServletResponse response, int seconds, boolean mustRevalidate)
    

    这两种方法都是WebContentGenerator中的实现

    【讨论】:

    • 嗨拉尔夫!我不知道会发生什么,但是当 Spring 启动时,WebContentGenerator 的 cacheSeconds 属性设置为 -1(默认情况下),但是当调用 applyCacheSeconds 时,cacheSeconds 为 0,调用 preventCaching。而setter方法setCacheSeconds只被调用一次……
    • @Marcelo Juventino:我可以解释这种行为的一种方式是,您“仍然”使用 AnnnotatopnMethodHanlder,就像 Tomasz 在他的(已删除)答案中建议的那样,而不是像您写的那样使用 WebContentInterceptor在你的问题中。
    • 嗨@Ralph!我尝试了两种解决方案,但都没有解决。贝娄,@Abhi 建议使用 HandlerInterceptor 并在解决的 preHandler 方法中实现解决方案。但这不是一个清晰而精细的解决方案。
    【解决方案4】:
    <mvc:interceptors>
        <bean id="webContentInterceptor" class="org.springframework.web.servlet.mvc.WebContentInterceptor">
            <property name="cacheSeconds" value="2100" />
            <property name="useExpiresHeader" value="false" />
            <property name="useCacheControlHeader" value="false" />
            <property name="useCacheControlNoStore" value="false" />
            <property name="cacheMappings">
                <props>
                    <prop key="/**/**">-1</prop><!-- removes pragma no-cache -->
                </props>
            </property>
        </bean>
    </mvc:interceptors>
    

    【讨论】:

      猜你喜欢
      • 2016-05-07
      • 2021-02-28
      • 2015-06-05
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-03
      相关资源
      最近更新 更多