Pages Navigation Menu

Coding is much easier than you think

Login Interceptor in Struts 2

Posted by on Aug 5, 2014 in Struts-2 | 7 comments

 
In our previous tutorial we have learned about concepts of interceptor and how interceptors gets execute before and after action class by creating a custom interceptor. In this article we shall create a custom LoginInterceptor which could be used in real time struts 2 application
 
Login Interceptor in Struts 2
 
This LoginInterceptor will perform these tasks:-

  • Check user exist in session or not.
  • Runs before every action to check .If someone try to access direct URL of welcome page and if he is not present in session then it will redirect towards login page.
  • If user already in session then call the action called by user.
  • If session time expired and if user clicks on any link, then redirect towards login page.

 
File : LoginInterceptor.java
 

package com.interceptor;

import java.util.Map;

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

public class LoginInterceptor  extends AbstractInterceptor {

        @Override
	public String intercept(ActionInvocation invocation) throws Exception {
		Map<String, Object> session = invocation.getInvocationContext().getSession();

		String loginId = (String) session.get("loginId");

		if (loginId == null) 
		{
			return Action.LOGIN;
		} 
		else 
		{
			return invocation.invoke();
		}
	}
}

 
Here LoginInterceptor class extended the “AbstractInterceptor” and in its intercept method we have written business which checks weather the user present in session or not.

In the intercept method, we can make use of com.opensymphony.xwork2.ActionInvocation i.e. Action Invocation object to get the action name trigger and decide on the further flow of application associated with it. On the similar lines we can also make use of the org.apache.struts2.ServletActionContext to get the request, response, session object etc. which can be used further to decide on flow of the application.

 
LoginAction.java
 

package com.action;

import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport implements SessionAware {

	private static final long serialVersionUID = 1L;
	private String userName;
	private Map<String, Object> session;

	public String home() {
		return SUCCESS;
	}

	// Log Out user
	public String logOut() {
		session.remove("loginId");
		addActionMessage("You have been Successfully Logged Out");
		return SUCCESS;
	}

	// Login user
	public String login() {
		if (userName.isEmpty()) {
			addActionError("Username can't be blanked");
			return LOGIN;
		} else {
			session.put("loginId", userName);
			return SUCCESS;
		}
	}

	public String getUserName() {
		return userName;
	}

	public Map<String, Object> getSession() {
		return session;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public void setSession(Map<String, Object> map) {
		this.session = map;
	}
}

 
LoginAction class with simple business logic, such as you can login with any username but cannot leave blank the mandatory fields.
 

Configuring the custom interceptors in struts.xml

 
Here we configure our custom interceptor named LoginInterceptor defining loginStack as default stack.
 

<struts>
<package name="default" extends="struts-default">
	<interceptors>
		<interceptor class="com.interceptor.LoginInterceptor" name="loginInterceptor">
		</interceptor>
		<interceptor-stack name="loginStack">
			<interceptor-ref name="loginInterceptor" />
			<interceptor-ref name="defaultStack" />
		</interceptor-stack>
	</interceptors>

	<!-- login action -->
	<action name="loginUser" class="com.action.LoginAction" method="login">
		<result name="success" type="redirect">homeAction</result>
		<result name="login">login.jsp</result>
	</action>

	<!-- home link action -->
	<action name="homeAction" class="com.action.LoginAction" method="home">
		<interceptor-ref name="loginStack" />
		<result name="login">login.jsp</result>
		<result name="success">home.jsp</result>
	</action>
	
	<!-- logout action -->
	<action name="logOut" class="com.action.LoginAction" method="logOut">
		<result>login.jsp</result>
	</action>
</package>
</struts>

 

web.xml:

 
In web.xml define session time out to 1 min, for demonstrating point 4
 

  <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>
  <session-config>
    <session-timeout>1</session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>

 

Demo

Now on running this application
 
Login Interceptor
 
Now on entering a valid User name and hitting Submit button, the following page get appeared.
 
Login Interceptor2
 
Now once I hit logout link or if the session gets expired, then if the try to access the localhost:8089/LoginInterceptor/homeAction url, then the application redirects to Login page as shown below.
 
Login Interceptor
 

Read More

Interceptors in Struts 2

Posted by on Aug 3, 2014 in Struts-2 | 0 comments

 

  • Interceptors are introduced as part of the Struts2 framework, power mechanism for controlling request and are responsible for the most of request processing.

 
Request Processing Life Cycle Workflow in Struts 2

  • Interceptors are invoked by controller before and after invoking action and sits between the controller and action.
  • An interceptor allows common, cross-cutting tasks to be defined into a clean, reusable component, which is different than the “action” code.
  • Tasks like data validation, type conversion, and file upload are done using interceptors in Struts2.0.
  • The built-in interceptors, declared in the “defaultStack” of the “struts-default package”, handle most of the fundamental tasks.

 

Functioning of Interceptors

  • From architectural point of view, interceptors improve separation of concerns in web applications.
  • An example of a pre-processing task is the data transfer achieved with the “params” interceptor.
  • Instead of having a simple controller that directly invokes an action, we now have a component that sits between the “controller” and the “action”.
  • In Struts 2, no action is invoked in isolation, the invocation of an action is a layered process. It always includes the execution of a stack of interceptors prior to and after the actual execution of the action itself.
  • Rather than directly invoking the action’s execute ( ) method, the framework creates an object called an “ActionInvocation”. This object encapsulates the action. Subsequently, all the interceptors that have been configured to fire before and after that “action” start their execution.

 

Interceptor Order

Diagrammatic Representation

actioninvocation

  • The figure above represents the normal workflow; here none of the interceptors have diverted the invocation. This “action” will ultimately execute and return a “control string” that selects the appropriate “result”.
  • After the “result” execution, each of the interceptors, in reverse order, gets a chance to do some post-processing work.
  • As we will see, the interceptors have access to the “action” and other contextual values. This allows them to be aware of what is happening during the processing.
  • One of the powerful functional aspects of “interceptors” is their “ability to alter the workflow of the invocation”.
  • As we noted, the figure shown in the above depicts an instance where none of the interceptors has intervened in the workflow. It thus allows the “action” to execute, and determine the result that should render the view.
  • Sometimes, one of the interceptors will determine that the “action should not execute”. In such cases, the interceptor can halt the workflow by itself by returning a “control string”.

 
In our next article we shall learn to implement a custom interceptor in struts 2
 

Read More

Creating Custom Interceptors in Struts2

Posted by on Aug 4, 2013 in Struts 2 Tutorial, Struts-2 | 0 comments

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.
 

Read More

ModelDriven Interceptors in Struts 2

Posted by on Apr 18, 2013 in Struts 2 Tutorial, Struts-2 | 0 comments

 
In our last article we have learned how to use a JavaBean class as a property in struts 2 action.
 
In this tutorial we will learn about Struts 2 support for model objects.
 
The Model object is a simple JavaBean object, which will be available to action class directly from ValueStack,
i.e we dont need to do deeper referencing to refer its attribute(JavaBeans attribute).
 
To make a JavaBean object as a model object, our Action class should implement ModelDriven interface which forces the getModel() method to be implemented. This method provides the model object to be pushed into the Value Stack.
 
Here the getModel() must be invoked earlier for populating its input properties with data from request parameters,
To make sure that the model is available in Value Stack when input parameters are being set, the ModelDrivenInterceptor is configured for the Action in struts.xml.
 
Most Popular Article for Reference

 
Since the ModelDriven interceptor is already included in the default stack, we don’t need to inculde modelDriven interceptor explicitly.
 
** UPDATE: Struts 2 Complete tutorial now available here.
 
Let’s see a sample example of POJO form, which can be injected in the action as its model.
 

Bean Class(Model Class)

 
File : User.java
 

package com.simplecode.bo;

public class User
{
	private String userName;

	public String getUserName() 
	{
		return userName;
	}

	public void setUserName(String userName) 
	{
		this.userName = userName;
	}
}

 

Action Class

 
Action class implements the ModelDriven interface, declared the getModel() method to return the user’s object. When the form data is submitted to this action, it will transfers the form data into the user properties automatically.
 
File : HelloAction.java
 

package com.simplecode.action;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;
import com.simplecode.bo.User;

public class HelloAction implements Action,ModelDriven<User> 
{
	// Need to initialize model object
	private User user = new User();
	
	public String execute() 
	{
		if (user.getUserName().isEmpty()) 
			return ERROR;
		else 
			return SUCCESS;
	}
	
	public User getModel() {
		return user;
	}
}

 
Note:
1. Since the model object to be pushed into ValueStack must not be null hence model must be initialized before returned by getModel() method.
2. We can use only one model object per action class
 
Do read :

  • Difference between Action Chaining & Action redirect in Struts 2
  • GridView in struts 2 using jQuery DataTable plugin
  • Autocomplete in Struts 2 using Jquery via Ajax
  •  

    JSP page

     
    JSP pages for the ModelDriven demonstration.
     
    login.jsp
     

    <%@taglib uri="/struts-tags" prefix="s"%>
    <html>
    <head>
    <title>Login</title>
    </head>
    <body>
    	<h3>Struts 2 ModelDriven Example</h3>
    
    	<s:form action="hello">
    		<s:textfield name="userName"  label="User name"/>
    		<s:submit name="submit" />
    	</s:form>
    </body>
    </html>
    

     
    success.jsp
     

    <%@ taglib prefix="s" uri="/struts-tags"%>
    <html>
    <head>
    <title>Welcome Page</title>
    </head>
    <body>
    	Welcome, <s:property value="userName" />
    </body>
    </html>
    

     

    error.jsp
     

    <%@ taglib prefix="s" uri="/struts-tags"%>
    <html>
    <head>
    <title>Error Page</title>
    </head>
    <body>
    Login failed! Please enter a valid user name
    </body>
    </html>
    

     

    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>
    	<package name="default" extends="struts-default">
    		<action name="hello" class="com.simplecode.action.HelloAction">
    			<result name="success">/jsp/success.jsp</result>
    			<result name="error">/jsp/error.jsp</result>
    		</action>
    	</package>
    </struts>
    

     

    Demo

     

    http://localhost:8089/ModelDriven/

    Model Driven 1
     
    When I enter a non empty value in the textbox and press submit button, then the application redirects to success page as shown.

    Model Driven 2
     
    On Clicking submit button without any value in textbox, then the application redirects to error page as shown.

    Model Driven
     

    Read More