Struts 2 Interceptors with Example

Interceptors : 

Interceptor is an object which intercepts an action dynamically. It executed before and after the action execution. It Allows the developers to write a code which can execute and after the action. It executed before and after the code. It can prevent an action before executing.  

Features like double-submit guards, type conversion, object population, validation, file upload, page preparation, and more, are all implemented with the help of Interceptors. Each and every Interceptor is pluggable, so you can decide exactly which features an Action needs to support.

As we have seen request workflow in Introduction to struts2 part.
  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.
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.Now Internal workflow is:
  • 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.

Goal :

We will create two interceptor class and one action class to show workflow . We will  also learn how to declare intercpetor and also to do mapping between interceptor and action in struts.xml.

Create project named "InterceptorsWorkflow".For configuring struts 2 in your eclipse ide please refer configuring struts 2 link.

Project structure:

Interceptor classes:

Create class FirstInterceptor.java in src folder.

copy following code in FirstInterceptor.java.

package org.arpit.javapostsForLearning;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class FirstInterceptor implements Interceptor{

    @Override
    public void destroy() {
        
        
    }

    @Override
    public void init() {
            
    }

    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        
        String startInterceptor="   Start Interceptor 1";
        System.out.println(startInterceptor);
        String result=actionInvocation.invoke();
        String endInterceptor="   End Interceptor 1";
        System.out.println(endInterceptor);
        return result;
    }

}
 
Create one more class SecondInterceptor.java in src folder. copy following code into SecondInterceptor.java
package org.arpit.javapostsForLearning;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;


public class SecondInterceptor implements Interceptor{

 @Override
 public void destroy() {
    
 }

 @Override
 public void init() {
  
 }

 @Override
 public String intercept(ActionInvocation actionInvocation) throws Exception {
  
  String startInterceptor="   Start Interceptor 2";
  System.out.println(startInterceptor);
  String result=actionInvocation.invoke();
  String endInterceptor="   End Interceptor 1";
  System.out.println(endInterceptor);
  return result;
 }

} 
Now both classes implements Interceptor interface. The Interface Interceptor (com.opensymphony.xwork2.interceptor ) extends Serializable interface and is a stateless class. The Interceptor Interface have three methods are as follows-
void destroy( ) - This method is used to clean up resources allocated by the interceptor.
void init( ) - This method is called at the time of intercept creation but before the request processing using intercept, and to initialize any resource needed by the Interceptor.
String intercept(ActionInvocation invocation ) - This method allows the Interceptor to intercept processing and to do some processing before and/or after the processing ActionInvocation.

We will see more about this later.

Struts.xml:

We have seen in previous tutorial that struts.xml defines mapping between request to corresponding action.

How to declare interceptor in Struts.xml:

In <package> tag in struts.xml, we can declare all our interceptors in <interceptors> tag.

<interceptors>
            <interceptor name="name of interceptor" class="fully qualified name of class">
<interceptors>

For attaching interceptors to action,we can use <interceptor-ref> under <action> tag

<interceptor-ref name="name of intercept"/>

so now we will declare two above interceptors in struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.custom.i18n.resources" value="LoginAction" />


    <package name="default" extends="struts-default" namespace="/">
        <interceptors>
            <interceptor name="firstInterceptor"
                class="org.arpit.javapostsForLearning.FirstInterceptor" />
            <interceptor name="secondInterceptor"
                class="org.arpit.javapostsForLearning.SecondInterceptor" />

        </interceptors>
                
        <action name="Dummy" class="org.arpit.javapostsForLearning.DummyAction">
        <interceptor-ref name="firstInterceptor"/>
        <interceptor-ref name="secondInterceptor"/>
            <result name="success">Welcome.jsp</result>
            <result name="input">login.jsp</result>
        </action>
    </package>
</struts>

Action:

We will create one action class named DummyAction.java under src.Action class will be same as created in previous tutorials.

package org.arpit.javapostsForLearning;
import com.opensymphony.xwork2.ActionSupport;

public class DummyAction extends ActionSupport{

    public String execute()
    {
        System.out.println("   In Action");
        return SUCCESS;
    }
}

JSP:


Create one jsp named "ForCallingAction.jsp" in Webcontent.We are creating this jsp just to call action.We will create a button.On clicking of that button an action "Dummy" will be called.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Dummy Action</title>
</head>
<body bgColor="lightBlue">
<s:form action="Dummy">
<s:submit value="For calling Dummy Action" align="center"/>
 </s:form>
</body>
</html>

Create another jsp named "Welcome.jsp" As In DummyAction class,execute returns "success" so we will be directed to this page.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
</head>
<body>
Welcome !!!
</body>
</html>

Web.xml:

Web.xml will be same as previous tutorials except that we will change welcomeFile to "ForCallingAction.jsp"
Copy following code into web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <display-name>InterceptorsWorkFlow</display-name>

 <filter> 
    <filter-name>
       struts2
    </filter-name>
    <filter-class>
       org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
 </filter>

 <filter-mapping>
     <filter-name>struts2</filter-name>
     <url-pattern>/*</url-pattern>   
 </filter-mapping>
 <welcome-file-list>
 <welcome-file>ForCallingAction.jsp</welcome-file>
 </welcome-file-list>
</web-app>


Run project:

right click on project->run as->run on server
copy resultant url to browser.We will get following page.


 On clicking on button "For calling Dummy Action"  We will get following page


 We got welcome page here but we are more interested in how interceptors worked.So when we will see our console we will get something like this









Request Workflow:

 ActionInvocation object is main part of interceptor.The information of the sequence in which these interceptors are executed for the action is stored in the ActionInvocation object in form of stack.

Action method will only called once the interceptor stack has been called fully.This means that once the first interceptors has been called successfully in the stack it will call next interceptor defined in the stack and there reference being stored in the stack this chain will keep on calling till last interceptor in the stack is called.

  invocation.invoke()

This call is key to call next interceptor  defined in the stack or of this is the last it will call the desired function in action class.

Now in other case suppose some of the interceptor failed say workflow it will return the result as INPUT and will halt the further execution of the interceptor and framework will output corresponding error JSP/template to user.

Then come the post processing in this case interceptors will be called in reverse order i.e. top most or latest executed interceptor will be called first and then so on so.

The idea for the post processing is to do any clean-up work or any other things which needs to be done(like cleaning up resources etc)

For the first interceptor,the invoke() method is called by the ActionProxy object.
so in our example

  • FirstInterceptor is called by ActionProxy object and intercept method is called and "start interceptor 1 " will be printed to console.
  • Now it calls next interceptor in the stack i.e. SecondInterceptor and intercept method is called and "start interceptor 2" will be printed to console.
  • As there are no more interceptors in the stack,so DummyAction's execute method is called and "In Action" will be printed to console.
  • Now as last interceptor i.e. SecondInterceptor will be called first so "end interceptor 2" will be printed to console.
  • Now first interceptor i.e. FirstInterceptor will be called and "end interceptor 1" will be printed to console.

Source code:

Source:Download without jars files 
Source + lib: Download with jars files

Now in next post,we will learn how to upload file on server in struts 2

Written by Arpit:

If you have read the post and liked it. Please connect with me on Facebook | Twitter | Google Plus

 

Java tutorial for beginners Copyright © 2012