Struts 2 сбрасывает заголовок кэша - PullRequest
0 голосов
/ 16 мая 2010

У меня странное поведение сбрасывания Struts2 при настройке параметра кэширования для моего изображения.

Я пытаюсь поместить изображение из БД в кэшируемое на стороне клиента. Для рендеринга изображения я использую (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();
}

Но когда изображение встроено в страницу, оно всегда перезагружается (Firebug показывает код 200), и ни Expires, ни max-age не отображаются в заголовке

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 

Понятия не имею, почему он исчез, может быть проблема в URL?Это формы с параметром:

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

Ответы [ 2 ]

2 голосов
/ 11 июня 2010

Наконец я обнаружил, что не так с моим кодом, это довольно странно, потому что он частично работает (изображение отображается).

Виновником является следующая строка:

HttpServletResponse response = ServletActionContext.getResponse();

Он должен быть заменен следующим:

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

Это похоже на магию, но очевидно, что оба ответа используют один и тот же поток вывода, но не контейнер объявлений заголовков.

0 голосов
/ 19 мая 2010

Не уверен, что это сработает лучше, но вы можете попробовать. Создайте пользовательский перехватчик, который изменяет заголовки ответа. Примерно так (заметьте, я этого не проверял):

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...