Pages Navigation Menu

Coding is much easier than you think

Creating Custom Interceptors in Struts2

Interceptor in Struts 2

In my previous post here I demonstrated about Concepts of Interceptor in Struts 2. In this post we will see how to create a simple interceptor that will execute and print a few lines to the server logs, both before and after an action is executed.
A few points need to be kept in mind before writing your own interceptors;

  • You can create your own custom interceptor in two ways
    a)Implement the Interceptor interface
    b)Extend the AbstractInterceptor class.
  • If You are implementing the Interceptor interface, you have to provide implementations to three methods :
    void destroy();
    void init();
    String intercept(ActionInvocation invocation) throws Exception;
  • The ‘init’ method is called before the ‘intercept’ method is called. An interceptor instance is created
    once and is reused over many requests. Hence the interceptor code must be written to be thread safe.
  • The ‘intercept’ is the place where you write the business logic code of your interceptor.
  • The ‘destroy’ method is executed on application shutdown and is used to release resources used by the interceptor that have been allocated in the init method
  • If you are extending the AbstractInterceptor class, you only need to override the method:
    String intercept(ActionInvocation invocation) throws Exception method to provide your own implementation.
  • In our example we will be extending the AbstractInterceptor class.

 

Action Class

 
Now lets create a dummy action class

package action;
  
import com.opensymphony.xwork2.Action;
  
public class DummyAction implements Action{
  
        public String execute()
        {
                System.out.println("Inside Action Class");
                return SUCCESS;
        }
}

 

Interceptors

 
create two interceptor classes and name it MyInterceptor1 and MyInterceptor2.

File : MyInterceptor1.java

package interceptors;
 
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
 
public class MyInterceptor1 extends AbstractInterceptor{
 
    @Override
    public String intercept(ActionInvocation ai) throws Exception {
        System.out.println("Inside MyInterceptor1- Before Executing Action class");
        String invocationResult = ai.invoke();
        System.out.println("Inside MyInterceptor1- After Executing Action class");
        return invocationResult;
    }
}

 
 
File : MyInterceptor2.java 

package interceptors;

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

public class MyInterceptor2 extends AbstractInterceptor{

@Override
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("Inside MyInterceptor2- Before Executing Action class");

String invocationResult = ai.invoke();

System.out.println("Inside MyInterceptor2- After Executing Action class");
return invocationResult;
}
}

 

Configuring Interceptor in struts.xml

 
The configuration of struts.xml should be as show below

<struts>
 <package name="default" extends="struts-default">
 <interceptors>
   <interceptor class="interceptors.MyInterceptor1" name="myInterceptor1"></interceptor>
   <interceptor class="interceptors.MyInterceptor2" name="myInterceptor2"></interceptor>
 </interceptors>
 
 <action class="action.DummyAction" name="dummyAction">
   <interceptor-ref name="myInterceptor1"></interceptor-ref>
   <interceptor-ref name="myInterceptor2"></interceptor-ref>
      <result name="success">/success.jsp</result>
 </action>
 </package>
</struts>

 

Jsp

 
File : index.jsp
This file triggers dummyAction during application start up which is used to Test Interceptors

<META HTTP-EQUIV="Refresh" CONTENT="0;URL=dummyAction">

 
Since the action is already configured such that the two interceptors will be called before and after it is executed, you can check your server logs to ensure that the interceptors are executing in the order as specified in the configuration.
 

Demo

 
On running the application, my Tomcat logs show the following :

Inside MyInterceptor1- Before Executing Action class
Inside MyInterceptor2- Before Executing Action class
Inside Action Class
Inside MyInterceptor2- After Executing Action class
Inside MyInterceptor1- After Executing Action class

 

Explanation

 
Consider the intercept method of MyInterceptor1. This method is called with an argument of type ‘ActionInvocation’. The ActionInvocation object is created by the struts framework and is used as a handle to the execution environment of the interceptor.
 
Since there are several interceptor defined in struts-default xml, the information of the sequence in which these interceptors are executed for the action is stored in the ActionInvocation object. The next interceptor in the sequence is called by calling the invoke() method of the ActionInvocation object. For the first Interceptor, the invoke() method is called by the ActionProxy object.
 
Since the invoke method causes the next interceptor/action in the sequence to be executed, the interceptor is in absolute control of the execution and can decide at any moment whether to proceed with the next step in the sequence or to return an error to the caller without proceeding.
 
Here the String value returned by the invoke() method in Interceptor is the value that is retrieved after the action have been executed. In our example, when the myInterceptor1 interceptor calls it’s invoke, control is passed on to the myInterceptor2, which in turn calls the action. The action upon execution returns “success” as the string, which is in turn returned to the myInterceptor2, which is in turn returned to ‘myInterceptor1′.
 
I our next article we shall learn to implement an Login interceptor which can be used in a real time application.
 

About Mohaideen Jamil