Struts2 Interceptors Tutorial with Example

Welcome to Part-5 of 7-Part series where we are discussing different aspects of Struts2 Framework. In the previous article we saw how to integrate Tiles framework with Struts2.

Today we will explorer the world of Interceptors in Struts2. We will see what Interceptors are and how to configure them in a Struts2 based web application.

Struts 2 Interceptors: Basics

Struts2 provides very powerful mechanism of controlling a request using Interceptors. Interceptors are responsible for most of the request processing. They are invoked by the controller before and after invoking action, thus they sits between the controller and action. Interceptors performs tasks such as Logging, Validation, File Upload, Double-submit guard etc.
struts2 request processing lifecycle
The request processing lifecycle of Struts2 framework is pretty much discussed Part 1 – Introduction to Struts2 Framework.

  1. Request is generated by user and sent to Servlet container.
  2. Servlet container invokes FilterDispatcher filter which in turn determines appropriate action.
  3. One by one Intercetors are applied before calling the Action. Interceptors performs tasks such as Logging, Validation, File Upload, Double-submit guard etc.
  4. Action is executed and the Result is generated by Action.
  5. The output of Action is rendered in the view (JSP, Velocity, etc) and the result is returned to the user.

Thus the Struts2 Interceptors removes cross cutting tasks such as logging from action components and create cleaner separation of MVC.

Struts2 comes with default list of Interceptors already configured in the application in struts-default.xml file. We can create our own custom Interceptors and plugin into a Struts2 based web application.

Framework creates an object of ActionInvocation that encapsulates the action and all the interceptors configured for that action. Each interceptors are called before the action gets called. Once the action is called and result is generated, each interceptors are again called in reverse order to perform post processing work. Interceptors can alter the workflow of action. It may prevent the execution of action.

Our Goal

Our goal will be to create a customer interceptor MyLoggingInterceptor, which will log the request before any action is called. Also it will prints the Action class name and execution time of action in milliseconds.

Create Logging Interceptor

Create a java class MyLoggingInterceptor in package net.viralpatel.struts2.interceptors and copy following content into it.
struts2-logging-interceptors

package net.viralpatel.struts2.interceptor;

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

public class MyLoggingInterceptor implements Interceptor{

	private static final long serialVersionUID = 1L;

	public String intercept(ActionInvocation invocation) throws Exception {

		String className = invocation.getAction().getClass().getName();
		long startTime = System.currentTimeMillis();
		System.out.println("Before calling action: " + className);

		String result = invocation.invoke();

		long endTime = System.currentTimeMillis();
		System.out.println("After calling action: " + className
				+ " Time taken: " + (endTime - startTime) + " ms");

		return result;
	}

	public void destroy() {
		System.out.println("Destroying MyLoggingInterceptor...");
	}
	public void init() {
		System.out.println("Initializing MyLoggingInterceptor...");
	}
}

Configuring Interceptor in struts.xml

Once we have created an interceptor class, all we need to do is to configure it in struts.xml file and use it with actions.

To configure newly created interceptor, add following code in struts.xml

		<interceptors>
			<interceptor name="mylogging" 
				class="net.viralpatel.struts2.interceptor.MyLoggingInterceptor">
			</interceptor>
			<interceptor-stack name="loggingStack">
				<interceptor-ref name="mylogging" />
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>

This code has to be added after <result-types > tag in <package ></package>
Here we have configured a new interceptor mylogging with tag <interceptor >. Also note that we have defined an interceptor-stack with name loggingStack. This is to make sure Sturts2 calls all the default interceptors as well while calling our custom interceptor. This is very important as the validation logic will not work in our struts2 application if we ignore the default stack of interceptors.

We can make the new loggingStack as default interceptor stack or can configure it at each action level. In order to make it default stack, we should add following in struts.xml

<default-interceptor-ref name="loggingStack"></default-interceptor-ref>

Once we add above code in Struts.xml, the logginStack will be applied to all the actions in that package.

Also we may want to apply the custom interceptor stack to only certain actions. To do so, we must add interceptor-ref tag in action.

<action name="login" 
	class="net.viralpatel.struts2.LoginAction">
	<interceptor-ref name="loggingStack"></interceptor-ref>
	<result name="success" type="tiles">/welcome.tiles</result>
	<result name="error">Login.jsp</result>
</action>

That’s All Folks

If we execute our StrutsHelloWorld application in Eclipse and see the console logs, we will find the log statements that we print in our interceptor.

Initializing MyLoggingInterceptor...
..
..
..
Before calling action: net.viralpatel.struts2.LoginAction
..
..
After calling action: net.viralpatel.struts2.LoginAction Time taken: 313 ms
..
..
..
Destroying MyLoggingInterceptor...

Download Source Code

Click here to download Source Code without JAR files (17KB)

Moving On

Today we saw what are Struts Interceptors and how to create a custom interceptor and configure it with a Struts2 based web application. In the next part we will see Struts2 File Upload Example.



26 Comments

  • Arpit 21 September, 2010, 18:14

    Dear Viral,

    Above is the code snippet from “Configuring Interceptor in struts.xml” section.

    I want to know what if i swap the order of interceptor declaration in strut.xml like this

    In other words, if i am creating my own interceptor, how to decide the order of precedence for interceptor.

    Thanks
    Arpit

  • Pratik Shah 28 October, 2010, 12:40

    Hi Viral,

    Are there any JAR files required for running interceptors?
    If so, what are they.
    I have used interceptors after creating the login application hello world and have just added the MyLoggingInterceptor.java and made the changes in struts.xml.

    Now, my struts.xml looks like this:-

    Welcome.jsp
    Login.jsp

    I am gettign Error 404, please help as in where am I missing simething.

  • Pratik Shah 28 October, 2010, 12:41

    Hi Viral,

    Are there any JAR files required for running interceptors?
    If so, what are they.
    I have used interceptors after creating the login application hello world and have just added the MyLoggingInterceptor.java and made the changes in struts.xml.

    Now, my struts.xml looks like this:-

    Welcome.jsp
    Login.jsp

    I am gettign Error 404, please help as in where am I missing simething.

  • Pratik Shah 28 October, 2010, 12:55

    Dear Viral,

    I have done the interceptor on the code for Hello world applicationa dn have added the MyLoggingInterceptor and corresponding code in struts.xml.

    I am getting error 404.
    Are there any jar files to be added for this?
    If so, what are they?

  • Pratik Shah 28 October, 2010, 13:41

    Dear Viral,

    The issue is solved.

    I was using the after in struts.xml and hence the error 404 – resource not found was getting displayed.

    It vanished when I used before in the in struts.xml.

    Thanks again.

  • Pratik Shah 28 October, 2010, 13:48

    Dear Viral,

    Under whcih event (on doign what is the destroy() called whcih will print :-
    public void destroy() {
    System.out.println(“Destroying MyLoggingInterceptor…”);
    }

  • ravi 19 November, 2010, 11:26

    Hi Viral,
    i am facing problem in implementtaion of <sx:autocompleter tag. Actually our reuirement is onselect of autocomplter we have to refresh a div having two ot three dropdown. in refreshing of div i am including one mode jsp that have only target Div .because in the same jsp we are not getting div refresh using Ajax updater as well so we have two jsp one have all the jsp contents and other one have only that div which to be refresh.
    Can you pls provide me any complete example that will help me .

  • syed 7 September, 2011, 15:20

    Tuitorial is Excellent for the Beginner thanx

  • suryaprakash 19 January, 2012, 10:00

    Thanks Viral ji

  • Sorina 10 May, 2012, 12:52

    Hi,

    I am having a problem with session, when passing through interceptor, when I get to my action, the session is null. Any ideas?

    thanks

    • Viral Patel 10 May, 2012, 14:06

      Hi,
      How are you accessing request object from your Interceptor?

      final HttpServletRequest request = (HttpServletRequest) ActionContext
                              .getContext().get(ServletActionContext.HTTP_REQUEST);
      Session session = request.getSession();
      

      Check if you are accessing session correctly!

      • Praveen 11 February, 2013, 11:50

        Consider following class declaration declared above

         public class MyLoggingInterceptor implements Interceptor
        

        Implement another Interface which is Sub Interface of Aware like following

        public class MyLoggingInterceptor implements Interceptor,ServletRequestAware {
        public void getServletRequest(HttpServletRequest request) { }
        }
        
  • Sumita Mudgil 22 May, 2012, 23:56

    Tutorial is excellent for beginners and is crystal clear. Thankx for sharing!!!

  • Shubhashree 25 July, 2012, 16:35

    Hello Viral
    I am facing problem for preserving the properties of an object from one action to another.
    I have gone throgh all struts docs and found that chaining interceptor can solve this.
    Kindly post an example which uses chaining interceptor to solve this problem.

  • Abhimanyu 11 October, 2012, 12:03

    Nice tutorial… :)

  • Rohit 14 October, 2012, 21:15

    With struts.xml package extending hibernate-default and with a interceptor configured a NullPointerException is thrown at Criteria criteria = session.createCriteria(LoginDTO.class); Anyway to resolve this? thanks in advance!

  • rav 2 November, 2012, 11:30

    superbbbbbbbbbbb tutorial for beginers

  • gangadhar 5 December, 2012, 18:49

    type Status report

    message /Struts2Starter/getTutorial.action

    description The requested resource is not available.

    SEVERE: Exception starting filter Struts2
    java.lang.ClassNotFoundException: org.apache.Struts2.dispatcher.org.filter.StructPrepareAndExecuteFilter
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:532)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:514)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:133)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:256)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:382)
    at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:103)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4650)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5306)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:619)

  • gangadhar 5 December, 2012, 18:50

    please replay

  • AB 21 December, 2012, 14:40

    make a proper entry of FilterDispatcher in to the web.xml pape. you can try it..

    struts2
    org.apache.struts2.dispatcher.FilterDispatcher

    struts2
    /*

  • Ashish 10 May, 2013, 13:24

    after using interceptor i am not able to access values that i have passed from index page
    can anyone help me out

    • Viral Patel 10 May, 2013, 14:32

      Can you pl elaborate your question? How are you passing values between pages?

  • vijay 11 June, 2013, 14:13

    Yes viral…it is not moving after:-

    Initializing MyLoggingInterceptor…
    Jun 11, 2013 2:09:30 PM com.opensymphony.xwork2.util.ObjectTypeDeterminerFactory
    INFO: Setting DefaultObjectTypeDeterminer as default …
    Jun 11, 2013 2:09:30 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["http-bio-8088"]
    Jun 11, 2013 2:09:30 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["ajp-bio-8009"]
    Jun 11, 2013 2:09:30 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 2363 ms
    Before calling action: net.vijaykrishna.struts2.LoginAction
    Jun 11, 2013 2:09:41 PM com.opensymphony.xwork2.validator.ActionValidatorManagerFactory
    INFO: Detected AnnotationActionValidatorManager, initializing it…
    After calling action: net.vijaykrishna.struts2.LoginAction Time taken: 159 ms

  • vijay 11 June, 2013, 14:19

    After clicking addcustomer the above error is recieving

  • Rajpal Singh 16 August, 2013, 20:39

    Hello sir,
    Iam creating a struts interceptor program from this tutorial but when iam running this program it is creating problem in web.xml file. It is showing error “requested source not available” but when i remove filter class tag and filter mapping tag the program is running means index.jsp page is showing and when i again add filter class and filter mapping tag it is not running can you tell me why????.
    Here is the web.xml code.

    StrutsInterceptor1

    struts2

    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

    struts2
    /*

    index.jsp

  • Marco 12 September, 2013, 15:55

    Hi viral,
    I’ve followed this Struts2 tutorial series and everything worked fine since now. Now it seems that the logging interceptor is not invoked, since I can’t see the logging messages in the console.
    I have to specify that I’m using jboss-6.1.0 as server-runtime.
    Any idea of what’s going on?
    Thanks in advance!

Leave a Reply

Your email address will not be published. Required fields are marked *

Note

To post source code in comment, use [code language] [/code] tag, for example:

  • [code java] Java source code here [/code]
  • [code html] HTML here [/code]