Satellite Internet QuickBooks Advice international calling cards calling cards
JavaBeat Certifications Certifications Kits Articles Tips QNA Interview Questions SCJP 1.5 SCBCD 5.0 Java/J2EE Feeds
Java Interview Questions Submit Your Blog Feedback Request Article Print Email

Struts 2.0 Introduction and Validations using Annotations

Author : Raja
Date : Wed May 30th, 2007
Topic : struts  
Pages :
Enter email address:

Latest JavaBeat Articles Delivered

1) Introduction

This article provides an introduction to Struts 2.0 and its new Validation Features. Since Struts 2.0 is new, the first few sections of the article discusses in brief about the basics of Struts 2.0, its architecture and its various New Features. The rest of the article is dedicated towards explaining about the new Validation Features available. Struts is an Open-Source Web Application Framework that simplifies the creation of a Java Web Application. It is based on the Model-View-Controller 2 (MVC 2) Architecture which was originally found in a language called SmallTalk. The recent version of Struts is Struts 2.0 and it has borrowed most of the concepts in terms of architecture and functionality from two frameworks namely WebWork and XWork.

2) Struts 2.0 - MVC Architecture

Struts 2.0 is based on MVC 2 Architecture. MVC is mainly concentrated in splitting the whole set of logic that happens in an Application into three different layers namely the Model, View and the Controller. In Struts 2.0, the Controller acts as a mediator between the View and the Model components. Whenever a request comes from a client, it is this Controller component who intercepts the request before being passed to Appropriate Handler.

Model represents the application data as well as the business logic that operates on the Data. Whenever the Framework routes the request to some Action class, the Action Class will do the Business Processing Logic which results in the State of the Application getting affected. After the application's state is affected, the control is returned back to the Controller which determines which View to be Rendered to the Client Application.

View is the Display Surface given as a response back to the Client populated with values. Struts 2.0 is not restricted in having JSP as its only View. Any View Technolgy can be chosen to render the Client Surface. It can be JSP, Velocity, Freemaker, or even XSLT. Even a brand new View technology can be plugged-in easily to the Struts Framework.

3) The Flow of a Struts 2.0 Application

The following are the sequence of steps that will happen when a Html Client makes a request to a Web Application built on top of Struts 2.0

  • The Client (which is usually a Html Browser) makes a Request to the Web Application.
  • The Web Server will search for the Configuration Information that is very specific to the Web Application (taken from the web.xml file), and will identity which Boot-strap Component has to be loaded to serve the Client's Request.
  • In Struts 2.0, this Component is going to be a Servlet Filter (whereas in Struts 1.0, the component is an Action Servlet).
  • The Filter Servlet then finds out the Action Class for this Request that is mapped in the Configuration File. File.
  • Before passing the Request to the Action class, the Controller passes the Request to a series of Interceptor Stack (explained later).
  • Then the Request Object is passed on to the corresponding Action Class.
  • The Action Class then executes the Appropriate Business Logic based on the Request and the Request Parameters.
  • After the execution of the Business Logic, a Result ("success" or "error") is returned either in the form of String or in the form of Result Object back to the Controller.
  • The Controller uses the Return Result to choose which View to be rendered back to the Client Application.

Let us look into the details of the major steps that was listed above.

3.1) Filter Servlet Loaded and Invoked by the Framework

A client makes a Web Request by typing the URL of the Web Application that is hosted in the Web Server something like the following, where localhost is the Machine Name where the Web Server is running, 8080 is the Port Number and hello is the Application Context for the Web Application.

					
http://localhost:8080/hello
					

Whenever a Request comes to a Web Application that is Struts 2.0 Enabled, the Web Server will search and load the Configuration Related Information that is very specific to the Application. In the case of a Struts 2.0 enabled Application, the Boot-Strap Component is going to a Filter Servlet. The Configuration Information about the Web Application will be maintained separately in web.xml file. Following is the Xml snippet taken from the web.xml file,

web.xml

					
<filter>
    <filter-name>Struts2FilterServlet</filter-name>
    <filter-class>
        org.apache.struts.action2.dispatcher.FilterDispatcher
    </filter-class>
</filter>
                    
<filter-mapping>
    <filter-name>Struts2FilterServlet</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
					

The above Xml Code tells that whatever be the Request URI Pattern (which is indicated by /*) that comes from the Client, identify the Component named by Struts2FilterServlet which happens to be the class org.apache.struts.action2.dispatcher.FilterDispatcher. The Identified Component is then instantiated and then passed with the Request Information.

3.2) Request Intercepted by Interceptors

Interceptors provide Pre-processing and Post-processing functionality for a Request or a Response object in a Web Application. For general information about Interceptors, readers can go through this section on JavaBeat. A Request Object usually passes through a Series of Interceptors before actually reaching the Framework. Assume that some kind of Authentication and Authorization related stuffs have to be done before a Request Object is being passed to a particular Module. In such a case, we can have the Core Business Logic that does the functionality of authorizing the Client Request in an Interceptor called AuthenticationInterceptor which does the Pre-processing works. Implementing a Custom Interceptor like this is very simple in Struts 2.0. The class structure may look like this,

AuthenticationInterceptor.java

					
package myinterceptors;

import com.opensymphony.xwork2.interceptor.*;

class AuthenticationInterceptor implements Interceptor{

    public void init(){}

    public void destroy(){}

    public String intercept(ActionInvocation invocation) throws Exception{
	
  	   // Get the value of user credentials from the Request and Validate it.
	   
    }
}
					

As we can see, writing a Custom Interceptor is as simple as writing a class that implements the Interceptor interface which is found in the com.opensymphony.xwork2.interceptor package. The method of interest is Interceptor.intercept() which has to be overriden along with the the appropriate business logic. Then the Custom Interceptor has to be made available to the framework by adding information in the Configuration File (struts.xml) as shown below,

struts.xml

					
<struts>

    ...	
    <interceptors>
        <interceptor name = "authentication" 
            class = "myinterceptors.AuthenticationInterceptor">		
        </interceptor>
    <interceptors>
   ...	
   	
</struts>
					

Interceptors are configured into the Web Application in the struts.xml file with the help of <interceptors> and <interceptor> entries. The name attribute is the alias name of the interceptor and it must be unique among the other set of Interceptor names. The class attribute identifies the actual implementation class for an Interceptor. The advantages of interceptors is not only limited to this. Interceptors can participate in so many different activities, to name a few - providing Logging Information to an Application, providing Encryption Facilities for the user input that used to get transmitted across layers, etc.. . Struts 2.0 already comes with a bunch of Built-in Useful Interceptors.

3.3) Performing some Action for a Request

After passing through a series of Interceptors, now it is time for the Framework to determine what Action has to be done for the Request. The Mapping between a Request and its Corresponding Action is configurable in the Xml Configuration File. Assume that in a Web Application, Regitration, Login and Logout represents the different set of actions. Let us have an assumptions that the operations are fairly complex, so that we tend to have individual classes for each of the operation. These things are configured in the struts.xml like the following,

struts.xml

					
<struts>

    <action name = "Registration" class = "hello.RegistrationAction">
    <action name = "Login" class = "hello.LoginAction">
    <action name = "Logout" class = "hello.LogoutAction">

</struts>
					

The Action Class usually acts as a Model and executes a particular business logic depending on the Request object and the Input Parameters. In earlier versions of Struts (before Struts 2.0), an Action class is supposed to extend the org.apache.struts.Action class and has to override the Action.execute() method which takes four parameters. Following is the code snippet of an Action class before Struts 2.0,

MyAction.java

					
package myactions;

import java.servlet.http.*;
import org.apache.struts.*;

class MyAction extends Action{

    public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws java.lang.Exception {
		
	    // Do some business logic here.
		
	}
}
					

In Struts 2.0, an Action class is made flexible as it can be a simple POJO Class. It means that the Action Class doesn't need to extend some class or implement an interface. It can be as simple as possible, and the following code snippet proves the same,

MyAction.java

					
package myactions;

import com.opensymphony.xwork2.*;

class MyAction extends Action{

    public String execute(){
        // Some logic here.		  
    }
	
}
					

Here comes the big question!. Then how can an Action class is supposed to access the HttpServletRequest and the HttpServletResponse objects to get the needed information!!! At this stage it is worth to mention about the Aware-Related Interfaces here. Suppose that an Action class wants to access the HttpServletRequest object. For this, it has to implement a special Aware Interface called ServletRequestAware and has to override the method setServletRequest(HttpServletRequest request) thereby storing it in an instance variable. So, the new modified action class becomes like this,

MyAction.java

					
package myactions;

import javax.servlet.http.*;

import com.opensymphony.xwork2.*;
import org.apache.struts2.interceptor.*;

class MyAction extends Action implements ServletRequestAware{

    private HttpServletRequest request;

    public String execute(){
    }

    public void setServletRequest(HttpServletRequest request){
        this.request = request;
    }
}
					

This above technique is basically an Inversion of Control. Inversion of Control is generally a Push Model which means that the data needed by the Application will be pushed by the Container or the Framework. In our case, we are making the Struts 2.0 Framework to call the method ServletRequestAware.setServletRequest(HttpServletRequest request) thereby populating the Request Object. Similar to this, there are Aware-Related Interfaces for Application, Servlet Request, Servlet Response, Parameters etc namely ApplicationAware, HttpServletRequestAware, HttpServletResponseAware, ParameterAware respectively.

3.4) Rendering the Result back to the Client

As we can see from the method signature, the return type of the Action.excute() method is just a String. This return type defines the Logical Outcome of the Action or the Page. Actual Outcome or the Response of a Page is configurable in the Struts Configuration File. Say the Action class can return a logical 'success' which tells that the action has be successfully processed or 'failure' which sadly tells that some thing wrong has happened in the Application. Some Predefined Constants have been defined in the Action interface for the logical outcomes namely, Action.SUCCESS, Action.ERROR, Action.LOGIN, Action.INPUT and Action.NONE. Consider the following code snippet,

MyAction.java

					
package myactions;

public class MyAction{

    public String execute(){

        if (createOperation()){
            return "create";
        }else if (deleteOperation()){
            return "delete";
        }else if( readOperation()){
            return "read";
        }else if  (writeOperation()){
            return "write";
        }
        return "error";
    }
}
					

The above method returns a bunch of Logical Outputs namely "create", "delete", "read" and "write". The logical outcomes should have their Corresponding Mappings defined in the struts.xml like the following,

struts.xml

					
<struts>
          
    …
    <action name = "MyAction" class = "myactions.MyAction">
        <result name = "create">/myApp/create.jsp</result>
        <result name = "delete">/myApp/delete.jsp</result>
        <result name = "read">/myApp/read.jsp</result>
        <result name = "write">/myApp/write.jsp</result>
    </action>
          
    …
</struts>
					

Submit Your Blog Feedback Request Article Print Email

Favorites
C# problem error
Free Newsgroups
Latest QnA
SCJD Tips
When we start a thread by applying start() method on it ,how does it knows that to execute run()method?
About Wrapper class in Java
How to configure weblogic 7.0 in MyEclipse?
Static Block and Static Initializer in Java

JavaBeat Website (2004-2009), India
javabeat | about us | useful resources
Copyright (2004 - 2009), JavaBeat