缓存标头拦截器什么都不做 - struts2

时间:2014-07-06 11:24:45

标签: java caching struts2

我正在使用Struts2开发一个Web应用程序。用户登录,发出请求然后注销。

当用户点击“后退”按钮(注销后)时,他不应该看到之前登录的页面,这意味着我想禁止浏览器缓存。我为此目的添加了一个拦截器:

public class CachingHeadersInterceptor extends AbstractInterceptor{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        // TODO Auto-generated method stub

        final ActionContext context = invocation.getInvocationContext();
        HttpServletResponse response = (HttpServletResponse)context.get(StrutsStatics.HTTP_RESPONSE);
        if(response!=null){
            response.setHeader("Cache-control", "no-cache, no-store");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "-1");

        }

        return invocation.invoke();
    }

}

此条目位于struts.xml文件中:

 <interceptors>

       <interceptor name="cachingHeadersInterceptor" class="com.proconsulto.interceptor.CachingHeadersInterceptor"/>
       <interceptor-stack name="defaultSecurityStack">
       <interceptor-ref name="defaultStack"/>
       <interceptor-ref name="cachingHeadersInterceptor"/>
       </interceptor-stack>

       </interceptors>

但是当我点击后退按钮退出后,我仍然可以访问该登录页面。

这里缺少什么代码?我已经按照在线教程编写了这段代码。

以下是异常跟踪:

WARNING: Unable to load config class com.proconsulto.interceptor.CachingHeadersInterceptor at interceptor - file:/C:/Users/AnkitaNallana/Desktop/OneMoreTime/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ProConsulto%20-%20Everything%20is%20fine%20-%20v16/WEB-INF/classes/struts.xml:21:117 probably due to a missing jar, which might be fine if you never plan to use the cachingHeadersInterceptor interceptor
Jul 08, 2014 3:21:26 PM com.opensymphony.xwork2.util.logging.commons.CommonsLogger error
SEVERE: Actual exception
Caught Exception while registering Interceptor class com.proconsulto.interceptor.CachingHeadersInterceptor - interceptor - file:/C:/Users/AnkitaNallana/Desktop/OneMoreTime/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ProConsulto%20-%20Everything%20is%20fine%20-%20v16/WEB-INF/classes/struts.xml:21:117
    at org.apache.struts2.impl.StrutsObjectFactory.buildInterceptor(StrutsObjectFactory.java:77)
    at com.opensymphony.xwork2.config.providers.InterceptorBuilder.constructInterceptorReference(InterceptorBuilder.java:70)
    at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.lookupInterceptorReference(XmlConfigurationProvider.java:1101)
    at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptorStack(XmlConfigurationProvider.java:919)
    at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptorStacks(XmlConfigurationProvider.java:932)
    at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadInterceptors(XmlConfigurationProvider.java:955)
    at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:524)
    at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:292)
    at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)
    at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:250)
    at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
    at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:429)
    at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:473)
    at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4584)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5262)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5257)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.ClassNotFoundException: com.proconsulto.interceptor.CachingHeadersInterceptor
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
    at com.opensymphony.xwork2.util.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:152)
    at com.opensymphony.xwork2.ObjectFactory.getClassInstance(ObjectFactory.java:108)
    at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:161)
    at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
    at org.apache.struts2.impl.StrutsObjectFactory.buildInterceptor(StrutsObjectFactory.java:52)
    ... 26 more

更加确定我复制了&amp;粘贴包装&amp;班级名称十几次,我仍然不知道为什么我得到ClassNotFoundException

另一种方法是在每个页面上将其写为JSP <% response.setHeader("xxx","vvv") %>标记。这非常乏味。我不想使用JS禁用它,因为这将是糟糕的用户体验。

我也注意到了另一件事。当我在几个JSP上使用<% response.setHeader("xxx","vvv") %>标签,然后点击“返回”按钮时,会显示一个重新加载按钮(在Chrome上) - 如果点击它 - 登录数据会被提交并且可以查看再次登录页面。我该怎么办才能保存此登录数据以便重新提交?

如果有类似的问题我可能没有遇到过 - 请在评论中提及其中的链接。我找不到答案,所以我在这里问!

2 个答案:

答案 0 :(得分:2)

示例总是比理论更好......

编辑:我只是向您展示演示。

package com.interceptors;

import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class CachingHeadersInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;

public String intercept(ActionInvocation invocation) throws Exception {

    if (ServletActionContext.getResponse() != null) {
        ServletActionContext.getResponse().setHeader("Cache-control",
                "no-cache, no-store, must-revalidate");
        ServletActionContext.getResponse().setHeader("Pragma", "no-cache");
        ServletActionContext.getResponse().setHeader("Expires", "-1");
        ServletActionContext.getResponse().setHeader("Vary", "*");
    }
    return invocation.invoke();
}

}

struts.xml

<package name="helloworld" namespace="" extends="struts-default">
   <interceptors>
     <interceptor name="cachingHeadersInterceptor" class="com.interceptors.CachingHeadersInterceptor"/>
     <interceptor-stack name="defaultSecurityStack">
         <interceptor-ref name="defaultStack"/>
         <interceptor-ref name="cachingHeadersInterceptor"/>
     </interceptor-stack>
   </interceptors>
   <action name="login" class="com.common.LoginAction" >
         <interceptor-ref name="defaultStack"/>          
         <interceptor-ref name="cachingHeadersInterceptor"/>

        <result name="success">/Home.jsp</result>
   </action>
  </package>

输出:这是响应标题

Cache Header Output

注销后,如果您想阻止用户查看页面,您可以实施Authorizeinterceptor

参考:参见AuthorizationInterceptor.java

的示例

在这个拦截器中,只需检查会话值,例如用户名,在注销后将为null,如果为null,则重定向到登录。

您可以创建新的拦截器,也可以将以下代码放在同一个CachingHeadersInterceptor.java

SessionMap<String,Object> map = (SessionMap<String,Object>) inv.getInvocationContext().getSession();
Object user = map.get("username");  
if(user==null ||user.equals("") || map.isEmpty() || map == null ){  
  return "login";   
}

struts.xml中将登录定义为重定向到登录页面的结果。

<global-results>
    <result name="login">login.jsp</result>
</global-results>

另请参阅我已在会话中添加和删除用户名LoginAction.javaLogoutAction.java

这很简单.... :)

答案 1 :(得分:1)

您是否将以下内容放在html head标签中:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Pragma" content="No-cache" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Expires" content="0" />

同时确保在退出后删除了会话。