2010-05-15 57 views
0

我设置缓存选项为我的图像时,struts2有奇怪的丢弃行为。Struts 2丢弃缓存标题

我试图把图片从数据库将在客户端缓存 要渲染的图像我使用(http://struts.apache.org/2.x/docs/how-can-we-display-dynamic-or-static-images-that-can-be-provided-as-an-array-of-bytes.html),其中特殊结果类型呈现如下:

public void execute(ActionInvocation invocation) throws Exception { 
    ...//some preparation 
    HttpServletResponse response = ServletActionContext.getResponse(); 
    HttpServletRequest request = ServletActionContext.getRequest(); 
    ServletOutputStream os = response.getOutputStream(); 
    try 
    { 
     byte[] imageBytes = action.getImage(); 
     response.setContentType("image/gif"); 
     response.setContentLength(imageBytes.length); 
     //I want cache up to 10 min 
     Date future = new Date(((new Date()).getTime() + 1000 * 10*60l)); 
     ; 
     response.addDateHeader("Expires", future.getTime()); 
     response.setHeader("Cache-Control", "max-age=" + 10*60 + ""); 
     response.addHeader("cache-Control", "public"); 
     response.setHeader("ETag", request.getRequestURI()); 
     os.write(imageBytes); 
    } 
    catch(Exception e) 
    { 
     response.sendError(HttpServletResponse.SC_NOT_FOUND); 
    } 

    os.flush(); 
    os.close(); 
} 

但是,当图像嵌入到网页它总是重载(萤火虫显示代码200),和没有到期,也没有最大年龄在头部

Host localhost:9090 
Accept image/png,image/*;q=0.8,*/*;q=0.5 
Accept-Language en-us,en;q=0.5 
Accept-Encoding gzip,deflate 
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive 300 
Connection keep-alive 
Referer http://localhost:9090/web/result?matchId=1 
Cookie JSESSIONID=4156BEED69CAB0B84D950932AB9EA1AC; 
If-None-Match /web/_srv/teamcolor 
Cache-Control max-age=0 

介绍我不知道它为什么dissapered,可在网址的问题?它是带参数的形式:

http://localhost:9090/web/_srv/teamcolor?loginId=3 

回答

2

最后我发现我的代码有什么问题,它很奇怪,因为它是部分工作(显示图像)。

罪魁祸首是以下行:

HttpServletResponse response = ServletActionContext.getResponse(); 

它必须改为:

HttpServletResponse response = (HttpServletResponse) 
    invocation.getInvocationContext().get(StrutsStatics.HTTP_RESPONSE); 

它看起来像是一种魔力,但显然都响应共享相同的输出流,但不标题声明的容器。

0

不知道这是否会更好,但你可以尝试。创建一个修改响应头的自定义拦截器。像这样的东西(注意,我没有测试过这一点):

package com.yourpackage.interceptor; 

import java.util.Date; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.struts2.StrutsStatics; 

import com.opensymphony.xwork2.ActionContext; 
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 

public class ResponseHeadersInterceptor extends AbstractInterceptor { 

    @Override 
    public String intercept(ActionInvocation invocation) throws Exception { 

     ActionContext context = invocation.getInvocationContext(); 
     HttpServletResponse response = (HttpServletResponse)context.get(StrutsStatics.HTTP_RESPONSE); 
     HttpServletRequest request = (HttpServletRequest)context.get(StrutsStatics.HTTP_REQUEST); 

     if (response!=null) { 
      Date future = new Date(((new Date()).getTime() + 1000 * 10*60l)); 
      response.addDateHeader("Expires", future.getTime()); 
      response.setHeader("Cache-Control", "max-age=" + 10*60 + ""); 
      response.addHeader("cache-Control", "public"); 
      if (request!=null) 
       response.setHeader("ETag", request.getRequestURI()); 
     } 

     return invocation.invoke(); 
    } 

} 

然后在你的struts.xml中,定义拦截器和一个新的拦截器栈:

<interceptors> 
    <interceptor name="responseHeaders" class="com.yourpackage.interceptor.ResponseHeadersInterceptor" />  
    <interceptor-stack name="extendedStack"> 
     <interceptor-ref name="defaultStack" /> 
     <interceptor-ref name="responseHeaders" /> 
    </interceptor-stack>   
</interceptors> 

然后修改你的行动定义使用extendedStack

+0

不幸的是结果是相同的 - 这意味着拦截器和结果类型都不会影响头。它由支柱携带 – Dewfy 2010-05-25 14:44:02