整了两天,终于找到一个比较满意的答案了:如何让action不被浏览器缓存
写一个interceptor:
package com.my.interceptor; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; @SuppressWarnings("serial") public class CacheInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { HttpServletResponse response = ServletActionContext.getResponse(); response.setHeader("Pragma","No-cache"); response.setHeader("Cache-Control","no-cache"); response.setHeader("Expires","0"); return invocation.invoke(); } }
在struts2中如果是普通的action(即没有加入convertion-plugin的),只需要在struts.xml直接配置interceptor即可。
但如果使用了convertion-plugin和rest-plugin,因为它是自动化完成action配置了,这时在struts.xml里所定义的interceptor就不起作用了。
必需这样写struts.xml:
<!-- 设置默认package --> <constant name="struts.convention.default.parent.package" value="default"></constant> <package name="default" namespace="/" extends="rest-default"> <interceptors> <interceptor name="cacheInterceptor" class="com.my.interceptor.CacheInterceptor" /> <interceptor-stack name="cacheStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="paramsPrepareParamsStack"></interceptor-ref> <interceptor-ref name="cacheInterceptor"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="cacheStack"></default-interceptor-ref> <default-action-ref name="index" /> <global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error"/> </global-exception-mappings> </package>
关键点有以下两点:
1)constant的value=package的name,如上。
2)cacheStack节点可以看到除了自定的cacheInterceptor外,还有两个stack:defaultStack和paramsPrepareParamsStack,这两个必不可少,否则如果action中使用了ModelDriven的都会失效。
失效原因:
defaultStack的作用是普通的param传递,paramsPrepareParamsStack是ModelDriven的对象传递。
如果在使用了自定的interceptor后,这两个stack将不再被调用,所以要手工加上去。