Table of Contents
This is 5 of 8 part of struts 2 tutorial.In this post,We will learn about interceptors and creating our own interceptor.
Tutorial Content:
Interceptors :
As we have seen request workflow in Introduction to struts2 part.
- Request is generated by user and sent to Servlet container.
- Servlet container invokes FilterDispatcher filter which in turn determines appropriate action.
- One by one Intercetors are applied before calling the Action. Interceptors performs tasks such as Logging, Validation, File Upload, Double-submit guard etc.
- Action is executed and the Result is generated by Action.
- 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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](https://java2blog.com/difference-between-serializable-and-externalizable-in-java/ “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:
1 2 3 4 5 |
<interceptors> Â Â Â Â Â Â Â Â Â Â Â <interceptor name="name of interceptor" class="fully qualified name of class"> <interceptors></interceptors></interceptor></interceptors> |
1 2 3 |
<interceptor-ref name="name of intercept"></interceptor-ref> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="UTF-8" ?> <struts> Â Â Â <constant name="struts.custom.i18n.resources" value="LoginAction"></constant> Â Â Â <package name="default" extends="struts-default" namespace="/"> Â Â Â Â Â Â <interceptors> Â Â Â Â Â Â Â Â Â <interceptor name="firstInterceptor" class="org.arpit.javapostsForLearning.FirstInterceptor"></interceptor> Â Â Â Â Â Â Â Â Â <interceptor name="secondInterceptor" class="org.arpit.javapostsForLearning.SecondInterceptor"></interceptor> Â Â Â Â Â Â </interceptors> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â <action name="Dummy" class="org.arpit.javapostsForLearning.DummyAction"> Â Â Â Â Â Â <interceptor-ref name="firstInterceptor"></interceptor-ref> Â Â Â Â Â Â <interceptor-ref name="secondInterceptor"></interceptor-ref> Â Â Â Â Â Â Â Â Â <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.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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.
1 2 3 4 5 6 7 8 9 10 |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" Â Â Â pageEncoding="ISO-8859-1"%> <%@taglib uri="/struts-tags" prefix="s" %> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Dummy Action</title> |
Create another jsp named “Welcome.jsp” As In DummyAction class,execute returns “success” so we will be directed to this page.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@taglib uri="/struts-tags" prefix="s"%> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Welcome</title> Welcome !!! |
Web.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?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><b>F</b>orCallingAction.jsp</welcome-file> </welcome-file-list> </web-app> |
Run project:
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:
1 2 3 4 |
<b>Source:</b><a href="https://dl.dropbox.com/s/3r3iqdeglz6i6f4/InterceptorsWorkflow.7z" target="_blank" rel="noopener">Download without jars files</a> <b>Source + lib</b>: <a href="https://dl.dropbox.com/s/bxjz9za2iz4rie3/InterceptorsWorkflowWithJars.7z?m" target="_blank" rel="noopener">Download with jars files</a> |
Now in next post,we will learn how to upload file on server in struts 2
Hi,
Will the interceptor intercepts the request before the jsp file configured in welcome file-list gets displayed. please clarify
Regards,
Bhaskar
Because dis is just a simple message displaying demo not a login demo.. So we do not need login action properties nor login.jsp