Clean Cache Struts2 Interceptor Tutorial

Page 1 of 2

The first tutorial concentrate on creating a basic interceptor, but useful in a typical web application.

This is very common that developer wants to restrict the browser to  cache rendered pages. And the way we used to achieve is having code similar to the following mostly in the JSP pages to prevent caching. Either we have this code in all the JSP pages or more friendly way is to have a common JSP page where we have this code and include it in all the main JSP pages.If we are using tiles or any such framework we follow the same strategy.

response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);

  

Struts2 helps us achieve this through interceptors and we don‘t want to have a JSP page to do this. This way we keep the code clean in JSP pages.

A little bit about interceptor before we start coding, interceptors are much like Servlet Filters as interceptors
follows the same design patters that a Servlet filter; intercepting filter.

Properties of Interceptors: 

  1. Interceptors executes twice per action execution. One before the action execute and after the action executes.
  2. The order in which interceptors execute matters a lot, and interceptors do  mean it. Though not all interceptors.
  3. Interceptors are not thread safe, since it is shared among all the action execution context ;so care should be taken.

Writing the interceptor:
Now that we know about the interceptors lets start.

package com.bullraider.apps.interceptors;

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

public class ClearCacheInterceptor  extends AbstractInterceptor{

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        return null;
    }
}

  

  1. The typical and most trivial way of writing an interceptor is to extend AbstractInterceptor class which has an abstract method that we  must override.
  2. The method intercept should execute invocation.invoke() in the intercept method. The reason is pretty similar to doFilter() method call of Servlet Filter inside doFilter() method. In plain English it means that if invocation.invokde() call is not there then the next interceptor lined up will not execute.
  3. The String return of the method is also very important, as this will help identify which result is returned
    from the action. This is could also be a place to modify the result value ( "success","error" etc) if required and a lot of interceptor do.If not sure then always return the value coming from invocation.invokde().

After these steps in consideration here is how the intercept method looks like.

public String intercept(ActionInvocation invocation) throws Exception {
        String result=invocation.invoke();
        return result;
}

  

Page 2 of 2

Now coming back to our clear cache implementation, we need to execute the setHeader() method on response object, but

we need to have the response object. BUT HOW ?
     
The answer is in the method signature :

public String intercept(ActionInvocation invocation)

  

To get response object we will make use of invocation object reference. Here is how.

ActionContext ctx=invocation.getInvocationContext();

  

ActionContext is the context in which the actions execute. So it has encapsulated many behavior and properties that represents the action execution context.

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

  

And we are done, finally my class looks like this:

package com.bullraider.apps.interceptors;

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 ClearCacheInterceptor  extends AbstractInterceptor{
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context=(ActionContext)invocation.getInvocationContext();
        HttpServletResponse response=(HttpServletResponse)context.get(StrutsStatics.HTTP_RESPONSE);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        String result=invocation.invoke();
        return result;
    }
}

  

One more important thing we skipped here is that 1st property of interceptor. When the interceptor is in pre processing state(before executing the next interceptor or action), it executes the lines of code that comes before the call to invocation.invoke() in the intercept method. And in post processing state it execute the lines comes after the invoke method.

In our code it seems meaningful only when we should have the code after the invocation.invoke() because the response is given back only in the post processing time. But If you try recollecting the Servlets request and response model, then it becomes clear that no matter where you keep the our code (before or after the call to invoke()).It does the same thing. So the 1st property of interceptor doesn’t apply to us in this situation.

Lets now stitch our interceptor in struts.xml.

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="test" extends="struts-default" >
        <interceptors>
            <interceptor name="clear-cache"
                class="com.bullraider.apps.interceptors.ClearCacheInterceptor" />
        </interceptors>
        <action name="Test" class="com.bullraider.apps.actions.TestAction" >
            <interceptor-ref name="clear-cache" />
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

  

Lets have a look at the action element, there is an element <interceptor-ref> and name with value clear-cache. What it means is ; apply this interceptor clear-cache in this action named Test.

The "clear-cache" is defined inside the <interceptor> element with value "clear-cache" and class as "com.bullraider.apps.interceptors.ClearCacheInterceptor". And this declaration has to be kept inside the <interceptors> element. We will have more discussion in the 3rd tutorial later.

And for obvious reason I am not going to discuss about the action class TestAction as follows.

package com.bullraider.apps.actions;

public class TestAction {
    public String execute(){
        System.out.println("Inside Action");
        return "success";
    }
}

  

Download  cacheinterceptorexample.war and run in your container to test it. Well if you are wondering how will you know if the headers applied in the response i.e success page. I use firebug extension for Firefox.

时间: 2024-10-14 08:06:40

Clean Cache Struts2 Interceptor Tutorial的相关文章

magento缓存系列详解:clean cache

cache是一个很大的概念,涉及的内容方方面面,magento cache是基于zend的,如果你对zend cache理解很深的话,相信magento cache也不再话下,本篇文章着重介绍Flush Magento Cache 和Flush Cache Storage 两个按钮的区别: 为了理解这两个选项之间的区别,你要先了解一些东西如缓存如何在 Magento 中工作.特别是要能准确的理解ids 和 tagging. 实质上,"id"就是一个唯一的字符串用来标识高速缓存中的共享存

Struts2 Interceptor学习

Interceptor的设计思想,其实是Spring里面的AOP思想,尽管Struts2又有自己的Interceptor但是,在实际开发中,用的较少,SSH整合之后你可以采用AOP事务处理进行拦截,更方便 ---------------------------------华丽的分割线--------------------------------------- 从一个简单的DEMO入手,正常情况下,客户端可以直接访问我的Action,但是我不想让他们访问,就在Struts2和Action之间架设

Struts2 Interceptor Life Cycle

Page 1 of 2 In the last tutorial we did successfully create a working interceptor, but there is more to it. To successfully develop bug free interceptors we need to know more. In this tutorial will try to understand a crucial part of interceptor. And

Struts2 interceptor使用经验小结

1. interceptor 调用Spring容器中的bean 在interceptor中常有需要调用Spring Bean的需要,其实很简单和Struts2的Action一样配置即可. Spring中的配置 <!--spring配置 -->1 <bean id="authorityInterceptor" class="com.xxx.interceptor.AuthorityInterceptor"/> 2 3 <bean id=&

Struts2中被误解的Interceptor

关于Struts2中的Interceptor,可谓是众说纷纭,五花八门,这里罗列一下网上常见的几种说法: 1.Interceptor的原理是动态代理.(尼玛,坑死人不偿命呀) 2.Interceptor的原理是责任链模式.(不要有个拦截器链就说是采用了责任链模式好不好) 3.Interceptor就是AOP.(尼玛,你了解AOP吗?) 4.Interceptor采用了AOP思想.(这个是对的) 5.Interceptor采用了AOP思想,所以它就是根据动态代理实现的.(对此我只想说,动态代理可以

Struts2的interceptor

从软件架构的角度讲:拦截器属于AOP编程的范畴.它将影响了多个业务对象的公共行为封装到一个个可重用的模块,减少了系统的重复代码,实现功能的高度内聚,确保了业务对象                             的整洁和纯度. 从java代码的角度讲:它就是一个普度的Java对象,它只需要实现一个名为Interceptor的接口. 当我们在struts.xml配置文件中包含struts-default包时,我们就会拥有默认的拦截器和拦截器栈.一个拦截器栈包含一组拦截器.堆栈中的每个拦截器

Struts2 拦截器(Interceptor )原理和配置

一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器. 比如:应用要求用户登陆,且必须为指定用户名才可以查看系统中某个视图资源:否则,系统直接转入登陆页面.对于上面的需求,可以在每个Action的执行实际处理逻辑之前,先执行权限检查逻辑,但这种做法不利于代码复用.因为大部分Action里的权限检查代码都大同小异,故

struts2拦截器interceptor的三种配置方法

struts2拦截器interceptor的三种配置方法方法1. 普通配置法 <struts>     <package name="struts2" extends="struts-default">         <interceptors>             <interceptor name="myInterceptor" class="edu.hust.interceptor.

Struts2(二):工作原理

struts可查看源码:https://github.com/apache/struts 在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自己要弄清这个框架的工作原理. struts2.1.3之前使用的FilterDispatcher,之后的版本使用StrutsPrepareAndExecuteFilter,而我这里还是以Dispatcher为例来记录的. 依据: Since Struts 2.1.3, use org.apache.s