Showing posts with label Struts 2. Show all posts
Showing posts with label Struts 2. Show all posts

Tuesday, March 1, 2011

Struts 2 Interceptors

In this guide I am going to show you how the struts 2 interceptors work.
Interceptors are new in Struts 2, those are classes that does not maintain a state and are automatically called before and after an action invocation.

Struts 2 has a number of interceptor that are called default on every action call, mapped in a stack, called defaultStack. The main default interceptors are the following:

  • Exception: allows to map a particular exception on a view;
  • Prepare: allows to call a method to initialize an Action if it implements a determined interface;
  • I18n: manage the locale for the current user;
  • Debugging: allows to activate the views debug;
  • FileUpload: allows to manage the file upload;
  • Validation: allows to validate the form fields, based on the xml validation files.
In the next picture I show you the default stack of interceptors:


If we implement a new custom interceptor for our application to be called before every action call as the default interceptors, we could create a new stack for it or put it in the default stack.
If we put it in the default stack, we need to list all the other interceptors defined default by struts, else it will not call those anymore. 
In the next picture I show you how I defined my interceptor in my struts.xml: 



As you can see from the picture above, I defined my new interceptor called loginInterceptor, then I listed the defaultStack with only the interceptors defined by struts 2.
Next, I created a new stack called mainStack on which I put my brand new interceptor and the default stack. 
After that I defined which one is the default stack that struts has to call: 
Here we tell Struts the default stack to call is the mainStack defined by me, in which there is my loginInterceptors and all the default interceptors referenced by the defaultStack.

Now I show you how to create an interceptor.
An interceptor class must extend the AbstractInterceptor abstract class of which we must implement the method  public String intercept(ActionInvocation invocation) throws Exception.
This method, as all the methods of struts actions, returns a String that in this case is the action that we are calling or, if any error occurs, any action defined by us to handle the error occurred.

My example of interceptor controls if the user that is using the application is logged in, looking for the session parameter userName. If the userName parameters is not null and not empty, it returns the action called by the user. If the user is not in session, but it is calling the loginAction to log in, then we return the action called by the user to allow him to log in. If the user is not in session, and the action called by the user is not the LoginAction, then we return a expiredSession result that sends the user back to the login page:


From the imageshowed above you can see that the ActionInvocation object has a lot of useful methods:
  • invocation.getAction().getClass().getName(): Those three methods allows us to retrieve the name of the action class called by the user;
  • invocation.invoke(): This method calls the action method to execute after the interceptor if everything works well inside it. 
You can see in the image the behavior of the interceptor that I expained before it.


Friday, February 25, 2011

Struts 2 Web Application

Let's see how to integrate Struts 2 in our Web Application.
First of all we need to import the necessary libraries in the lib folder, we don't need to import all the libraries that come with Struts 2 zip package.


After that, we need to modify the application descriptor file (web.xml) introducing the Struts2 filter that is called on every action call: 

You can see from the web.xml picture that between the application name and the welcome-file I have inserted the Struts 2 filter and his mapping.
The most important file that Struts 2 needs for doing his job is the struts.xml file. Differently from Struts 1, the new version of the framework wants this file in the src folder of the project. Remember that Struts 1 needed this file, called struts-config.xml, in the Web Content folder of the web project. 
There are some differences from the previous and this version:
- There are not the forward tags, because now we only need to specify a result tag with the name and the type of the result. The result type could be and redirectAction, a tiles, a jsp page in which case we don't need to specify the type, a jasper page, and so on...;
- There are not the ActionForm because we insert the form properties directly on the actions, so those are seen from the jsp without the need to specify any ActionForm.
A new important feature of Struts 2 are the Interceptors. Almost everything in Struts 2 is made by the interceptors, and you can create your own specifying it in the struts.xml and creating the stack that manages it or inserting it in the default interceptor stack.
In the following picture you can see my struts.xml file and the action login:



This action has two results: the input result that is called when we have any error when inserting data on the form, that returns the same page. The success result that specifiies the loggedIn page as the next page we can see on the browser when the form has no errors.
In the next image, I'll show you the LoginAction that you saw declared in the struts.xml file. The Struts 2 Action classes extends the ActionSupport class and not the Action class as Struts 1 did. In the new version we must override the execute method that does not have any parameter and returns a String that is the name of the result that we specified in the configuration file. 


As you can see from the image, I have only an instance variable that is of kind Account. I also need the getter and setter for this instance variable. In the execute method, the only thing that I do is looking if the values of account.userName and account.password matches "Alberto" and "Faedda" and, if the condition is true than I return the success result, else I add an action error and return the input result.
Another different thing that Struts 2 has from Struts 1 is how it uses the validation. In the previous version we had a unique validation.xml file in the Web Content folder, in which we specified every form of our application that we wanted to validate.
In this version we do have a different validation file for every form we want to validate, and we must create the file on the same package in which the action to which the form submits the parameters to, and his name will be <Action-name>-validation.xml.
It is much easyer to compile, because we don't have to specify the name of the forms on the file but only the fields we want to validate and the validation type for every field.
In the validation file of my login form, I only validate two fields: the username and password, and I look if those fields are not blank, else it shows an error in the jsp page, over the field in error without the need to add tags in the jsp page: 


In the jsp page, I imported the struts 2 taglib, specifying as prefix for its use the s letter.
The form tag has as attributes the action name that will be called at the submission and the method type for the parameters tobe sent. We can also see the two textfields in which the name attribute is the name of the instance variables of the action class, in my case the Account instance variables userName and Password. After the submit tag, I have the actionerrors tag that specifies where in this page will be shown the error that occurs if the account login form submitted is wrong.

As you can see from the image, I don't have specified any other tag for the validation erorrs. It only needs to know the parameters name and the name of the action, specified in his ownfile name, and if any error occurs for the field, it automatically shows the error before the field.
The next image shows the index page. It is the page that we see when we start up the application to make the login.

Let's now see how we'll see the application in the web browser:
This is the index page in which we have our login form with the two textfields and the submit, and a register link under the form. 
If we press the submit button and leave any textfield blank, as I told you before, we'll see the field errors that struts automatically set over the fields: 

When we fill the form, and the field values on the fields doesn't match the values that I specified on the LoginAction class, it shows the actionerror under the form, where I set the tag: 
If I insert the correct username and password I will log into the application...

 ...and it will show me the next page: