You are on page 1of 6

* Struts 2 Framework was implemented based on two popular Web Framework called Struts 1 and Web Works (xworks).

* Struts 2 Framework was implemented on MVC architecture and Front Controller Design Pattern.
* Struts 2 offers two different style to implement application (1) XML based Configuration (2) Annotation based Configuration
* Struts 2 required – Servlet API 2.4, JSP API 2.0, JAVA 5

* Struts Features :
 Simple POJO based Actions
 Simplified testability
 Thread Safe
 AJAX Support
 jQuery Plugin
 Dojo Plugin (deprecated)
 AJAX Client Side Validation
 Template Support
 Support for different result types
 Easy to extend with Plugins
 REST Plugin (REST based Actions, Extension-less URLs)
 Convention Plugin (Action Configuration via Conventions and Annotations)
 Spring Plugin (Dependency Injection)
 Hibernate Plugin
 support in Design
 JFreechart Plugin (Charts)
 jQuery Plugin (AJAX Support, UI Widgets, Dynamic Table, Charts)
 Rome Plugin (RSS Feeds)

* Struts 1 used a Servlet Controller such as the ActionServlet class while Struts 2 used Filter to perform same task.
* Struts 1 provided several tag libraries like Html, bean, logic etc that allow using custom tag in JSP while Struts 2
provides single Tag library that covers all.
* In Struts 1 all the tasks are done by a single component called RequestProcessor. There are some limitations with this
RequestProcessor while in the case of Struts 2 all the tasks are done by Interceptors. There are various interceptors implemented in
Struts 2 for various tasks.
* Struts 1 uses Form bean class but Struts 2 does not use Form bean class.

struts.xml :
<struts>
<constant name=”struts.devMode” value=”true”/>
<package name=”” namespace=”” extends=”” abstract=””>
<action name=”” class=”” method=””>
<result name=”” type=””></result>
</action>
</package>
<include file=”student-config.xml”/>
<bean type=”” name=”” class=”” scope=”” static=”” optional=””>
</struts>

<%@ taglib uri="/struts-tags" prefix="s" %>

Struts 2 offers 3 ways to implement Action Class :


1. POJO class without extending and implementing anything
In this approach, our Action class must override execute() method.
This approach has many limitations :
# We can not perform validation on input data. # We can not add errors message.
# We can not access properties from Message Bundle. # We can not access the locale related to the current.

2. Write Action class by implementing Action Interface


# In this approach, we must override execute() method of Action class.
# This approach has many limitations same as previous

3. Write class extending ActionSupport class.


# In this approach, we must override Action class execute() method.
# This approach gives full power to our Action class to use the functionality of ActionSupport.

Struts2 Dependency Injection :


Struts 2.0 provides the various Aware Interfaces to inject various Web Container Objects and data in the Web Container Objects :
# ServletRequestAware public void setServletRequest(HttpServletRequest request){}
# ServletResponseAware This interface is used to inject the HttpServletResponse object into our action. This interface has the
public void setServletResponse(HttpServletResponse response){} method,
which sets HttpServletResponse object.
# SessionAware used to handle client session within our Action. The SessionAware interface has the method
public void setSession(Map session){} to set the Map of session attributes in the implementing
action class. The action implementing SessionAware interface can access session attributes in the form of Session
Map. We can add, remove and obtain different session attributes by manipulating this Map.
# RequestAware
# ApplicationAware used to expose a method to an action class which sets an Application Map object in this action class. This Map
object contains different objects which are accessible from whole application, i.e. these are objects stored in
application scope. The key / values added into this Map is available similar to other application scope attributes.
The ApplicationAware interface has one method, public void setApplication(Map app){}
which sets the map of application properties in implementing class.
# CookiesAware
# ParameterAware The org.apache.struts2.interceptor.ParameterAware interface is used when an action wants to handle input
parameters. All the input parameters with its name/value are set in a parameter Map. When the actions require
the HTTP request parameter Map, then this interface is implemented within our Action. Another common use for
this interface is to propagate parameters to internally instantiate data objects. All the parameter values for a given
name will return String data, so the type of the objects in the Map is String[] data types.
The ParameterAware interface has one method public void setParameters(Map params){}
which sets the map of input parameters in the implementing class.

ActionContext : ActionContext is the centralized object which contains ValueStack, Web Container objects like Request, Response,
Session, Application, ServletContext etc. related to the request currently under Processing.

ValueStack : ValueStack is the centralized object which contains one or more Action Class instances.

OGNL (Open Graph Navigation Language) helps us to access the data from ActionContext inside JSP’s.
OGNL is a powerful expression language that is used to reference and manipulate data on the ValueStack. OGNL also helps in data
transfer and type conversion. The OGNL is very similar to the JSP Expression Language. OGNL is based on the idea of having a root or
default object within the context. The properties of the default or root object can be referenced using the markup notation, which is the
pound symbol.

(a) Accessing Action Class Variables which are of –


Simple types like String, date, Wrappers and Primitives.
Complex types (User-defined types / Java Class) like Customer, User etc. and Collection types.
(b) Accessing Attributes from Request, Session, Application which are of –
Simple types like String, date, Wrappers and Primitives.
Complex types (User-defined types / Java Class) like Customer, User etc. and Collection types.

When we deploy Struts 2 Application then Container will do following tasks:


1. holds the context object.
2. creates the request object.
3. creates the response object.
4. creates/holds the session object.
5. fd.doFilter(request, response, fc);

public void doFilter(request, response, fc){


 Creates the ActionContext Object.
 Creates the ValueStack and stores that ValueStack in ActionContext object.
 Stores the request in ActionContext object.
 Takes the session from Container and stores in ActionContext.
 Takes the context from Container and stores in ActionContext.
 Identifies the Action class.
 Action class instance will be created and will be placed in ValueStack.
 Identifies the Interceptors.
 Invokes all the Interceptors.
 execute() method will be called.
}

public class LoginAction extends ActionSupport{


public String execute() throws Exception{}
public void validate(){}
}

public class ActionSupport


extends Object
implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable

The ActionSupport class implements Action interface which exposes the execute() method.
The execute() method and following constants are declared in the Action interface which can be used as return values in the execute()
method.
public static final String ERROR = "error"
public static final String INPUT = "input"
public static final String LOGIN = "login"
public static final String NONE = "none"
public static final String SUCCESS = "success"
 ERROR is returned when the action execution fails.
 INPUT is returned when the action requires more input from the user.
 LOGIN is returned when the user is not logged into the system.
 NONE is returned when the action execution is successfull and there are no views to display.
 SUCCESS is returned when the action executed successfully and the corresponding result is displayed to the user.
Now lets see the roles played by the different interceptors.
# params interceptor helps in transfering the request data onto the action object.
# workflow interceptor controls the flow of cotrol.
The workflow interceptor checks whether the action implements the Validateable interface , if it does, the workflow interceptor will
invoke the validate() method of the Action class.
Note : validate() method available in Validateable Interface.

Struts 2 Interceptors :
* Interceptors are responsible for most of the request processing.
* Interceptors help inject custom logic into the request processing pipeline.
* They are invoked by the controller (FilterDispatcher) before and after invoking action, thus they sit between the controller and action.
* Interceptors perform tasks such as Logging, Validation, File Upload, Exception Handling, Double-submit guard etc.
* Struts2 comes with default list of Interceptors already configured in the application in struts-default.xml file which is available in
struts2-core-2.0.11.2.jar file.
* Struts2 Interceptors are conceptually very similar to Servlet Filter.
* We can create our own custom Interceptors and plugin into a Struts2 based web application.
* 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.

There are following methods of ActionInvocation Class :


1. public void init()
2. public String intercept(ActionInvocation invocation) throws Exception
3. public void destroy()

void init() - called after an interceptor is created, but before any requests are processed using intercept, giving the Interceptor a
chance to initialize any needed resources.

String intercept(ActionInvocation invocation)throws Exception –


Allow the Interceptor to do some processing on the request before and/or after the rest of the processing of the request by
the ActionInvocation or to short-circuit the processing and just return a String return code.
Returns: the return code, either returned from ActionInvocation.invoke(), or from the interceptor itself.
Throws: Exception - any system-level error, as defined in Action.execute().

void destroy() - Called to let an interceptor clean up any resources it has allocated.

Steps to implements Custom Interceptors :


1. Write our Interceptor class by implementing Interface called Interceptor or extends AbstractInterceptor class.
import com.opensymphony.xwork2.interceptor.Interceptor;
2. Override the following 3 methods :
public void init(){}
public String intercept(ActionInvocation invocation)throws Exception{
//Pre processing
logMessage(invocation, START_MESSAGE);
String result = invocation.invoke();
//Post processing
logMessage(invocation, FINISH_MESSAGE);
return result;
}
public void destroy(){}
* 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.
* Implement the required pre-processing logic inside the intercept() method before calling invoke() method and implement the
required post-processing logic inside the intercept() method after calling invoke() method.
* 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 we are extending the AbstractInterceptor class, then we only need to override the method :
String intercept(ActionInvocation invocation) throws Exception method to provide our own implementation

Register our Custom Interceptor in struts.xml as follows :


<package name=”jlcindia” extends=”struts-default”>
<interceptors>
<interceptor name=”jlcintercept” class=”com.jlc.struts2.JLCInterceptor”/>
<interceptor name=”stuintercept” class=”com.jlc.struts2.STUInterceptor”/>
</interceptors>
</package>
Referred the required registered built-in or custom interceptor under <action> as follow :
<action name=”Hello” class=”com.jlcindia.HelloAction”>
<interceptor-ref name=”alias”/>
<interceptor-ref name=”execAndWait”/>
<interceptor-ref name=”jlcintercept”/>
<interceptor-ref name=”stuintercept”/>
</action>
We can define the Stack of Interceptors without specifying list of Interceptors every time for every Action :
<package name=”jlcindia” extends=”struts-default”>
<interceptors>
<interceptor-stack name=”JLC1Stack”>
<interceptor-ref name=”exception”/>
<interceptor-ref name=”alias”/>
<interceptor-ref name=”jlcintercept”/>
</interceptor-stack>
</interceptors>
</package>
Referred the required Interceptor Stack under <action> as follows :
<action name=”Hello” class=”com.jlcindia.HelloAction”>
<interceptor-ref name=”JLC1Stack”/>
</action>
<action name=”Hai” class=”com.jlcindia.HaiAction”>
<interceptor-ref name=”JLC2Stack”/>
</action>

Strusts 2 provides two types of Validations : 1. Basic Validations 2. Validation Framework Validations.
Basic Validation: Steps to use Basic Validation :
 We have to override the validate() method in the Action Class.
 Our Action Class must implement Interface called Validateable.
 Workflow Interceptor should be invoked.
 We should specify the result with name “input”.
Validation Framework Validations :
[i] XML based Validations [ii] Annotations based Validations

# XML based Validations : required, requiredString, int, double, date, expression, fieldExpression, email, url, Conversion, Stringlength, Regex

Steps to use built-in XML based Validations :


1. Validation interceptor should be invoked.
2. We need to specify the validations required for various fields of Action Class in a separate xml file with the name called
[Action_Class_name]-validation.xml (Place where Action class is present)
Action Class Name : LoginAction.java XML Validation File Name : LoginAction-validation.xml

<validators>
<field name="username">
<field-validator type="requiredstring">
<message>Username is Required</message>
</field-validator>
<field-validator type="stringlength">
<param name="minLength">5</param>
<param name="maxLength">15</param>
<message> ${username} is Invalid. Username length must be between
${minLength} and ${maxLength} Characters long.
</message>
</field-validator>
</field>
</validators>

3 . We should specify the result with name “input”.

Steps to develop the Custom Validations:

import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;
public class MyEmailValidator extends FieldValidatorSupport{
public void validate(Object obj)throws ValidationException{
String fieldName=getFieldName();
String fieldValue=(String)getFieldValue(FieldName, obj);
// Our logic goes here………
}
}
public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator

Steps to Register and Use the Custom Validators :


1. Register in validators.xml (validators.xml must be placed under src folder)
<validators>
<validator name=”myemail” class=”com.struts2.MyEmailValidator”/>
<validators>
2. Use the Custom Validator in [Action_class_Name]-validation.xml As follows :
<validators>
<field name=”email”>
<field-validator type=”myemail”>
<message key=”myemailString”/>
</field-validator>
</field>
</validators>

# Annotation based Validations :


--------------------------------------------
Following are the list of built-n validators for Annotation Configuration.
 @Validation Note : place before a class declaration
 @RequiredStringValidator(message=”Username is required”)
 @RequiredFieldValidator(message=”Age is Required”)

 @StringLengthFieldValidator(message="Username must contains minimum of ${minLength} to maximum of ${maxLength}


characters", trim=true, minLength="5", maxLength="8")

 @IntRangeFieldValidator (message="Age must be minimum ${min} and ${max}", min="18", max="28")

 @DateRangeFieldValidator (message="DOB must be between ${min} and ${max}",min="01/01/80", max="01/01/90")

 @DoubleRangeFieldValidator (message="Fee must be between ${minExclusive} and


${maxExclusive}",minExclusive="900.50",maxExclusive="999.50")

 @EmailValidator (message=”Invalid Email”)

 @UrlValidator (message=”Invalid Website”)

 @CustomValidator (type="passwordstrategy", fieldName="password", message="Your password must contains one letter, one
number, and one of the following special Character--$!@#?")

Steps to use built-in Annotation based Validators


1. Validation Interceptor should be invoked.
2. We need to specify the validations required for various fields of Action class in inside the Action class only.

@Validation
public class AnnotedTest extends ActionSupport{
public String username;
@RequiredStringValidator(message=”Username is Required”)
@StringLengthFieldValidator(message=”Username must contain minimum of ${minLength} to Maximum
of ${maxLength} Characters”, trim=true, minLength=”5”, maxLength=”8”)
Public String getUsername(){
return username;
}
Public void setUsername(String username){
this.username=username;
}
}
3. We should specify with name “input”.

Steps to Develop the Custom Validators


Same as XML Validation

Steps to Register and use the Custom Validators

1. Specify the following <validator> tag under validators.xml


<validators>
<validator name=”myemail”
class=”com.jlc.struts2.MyEmailValidator”/>
</validators>

2. Use the Custom validator as follows


@CustomValidator(type=”email” message=”Your email is not in valid format”)
public String getEmail(){
return email;
}

Struts 2 - Tiles 2 Integration (Not a part of Struts2 Framework)


Tile Framework is mainly a Layout design framework which allow us to centralize the web page layouts, text formats, styles
required etc. Note : tiles.xml should be in WEB-INF folder and will contain various Tiles Definitions.

* To integrate Tiles 2 Framework with Struts 2 we have to add the following <listener> in web.xml
<listener>
<listener-class> org.apache.struts2.tiles.StrutsTilesListener </listener-class>
</listener>

* Specify the <context-param> in web.xml


<context-param>
<param-name>tilesDefinitions</param-name>
<param-value>/WEB-INF/tiles.xml</param-value>
</context-param>

* Specify the <result-types> in struts.xml


<package name="jlcindia" namespace="/jlcindia" extends="struts-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
<action name="DisplayAddContactForm" class="com.struts2.tiles.AddContactForm">
<result name="success" type="tiles">JLCAddContactDef</result>
</action>
Struts 2 integration with Spring MVC
-------------------------------------------
In Web.xml file

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springConfig.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>

You might also like