2010-04-01 48 views
8

我想为所有image/*text/css设置Expires标头。我正在做这个Filter。但是:如何添加基于内容类型的响应标头;在提交响应之前获取Content-type

  • 主叫内容类型还没有“意识到”
  • 主叫内容类型被设置之后,但这样是内容长度,即禁止增加新的报头(至少在之前Tomcat的实现)

我可以使用所请求的资源的扩展,但由于某些CSS文件由RichFaces的产生由内JAR-文件服用它们,文件的名称不是x.css,但是/xx/yy/zz.xcss/DATB/...

那么,有没有办法在提交响应之前获取Content-type。

回答

13

是的,执行HttpServletResponseWrapper并覆盖setContentType()

class AddExpiresHeader extends HttpServletResponseWrapper { 
    private static final long ONE_WEEK_IN_MILLIS = 604800000L; 

    public AddExpiresHeader(HttpServletResponse response) { 
     super(response); 
    } 

    public void setContentType(String type) { 
     if (type.startsWith("text") || type.startsWith("image")) { 
      super.setDateHeader("Expires", System.currentTimeMillis() + ONE_WEEK_IN_MILLIS); 
     } 
     super.setContentType(type); 
    } 
} 

和按如下方式使用它:

chain.doFilter(request, new AddExpiresHeader((HttpServletResponse) response)); 
+0

当然..我应该想到这个..尤其是当在同一个过滤器中使用另一个包装(因为另一个原因).. :) – Bozho 2010-04-01 20:51:09

+0

(只有,它不会是0,而是未来的一个时间) – Bozho 2010-04-01 20:58:13

+0

当然可以。或者你使用JodaTime? ;) – BalusC 2010-04-01 21:02:48

2

您应该继承HttpServletResponseWrapper并覆盖addHeadersetHeader,以在传入“Content-Type”作为标题名称时添加新的所需标题。请确保不要忘记在那些重写的方法中也调用super。用这个新的Wrapper包装doFilter方法参数中发送的响应,并将Wrapper传递给doFilter的调用。

+0

(+1)你和BalusC的答案都是正确的解决方案,但他是一个有点清洁(至少对我来说,因为一个不所谓一般方法被覆盖) – Bozho 2010-04-01 20:52:24

+0

是的,我错过了setContentType方法。您可能会考虑对setHeader和addHeader执行相同的操作,因为您永远不知道它是如何编码的。除非你拥有所有的代码。 – laz 2010-04-01 21:13:15