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

Wednesday 14 August 2013

Top Most Struts 2.X - XML Based Validation Code

This sample explains about how to do a XML based Validation in Struts 2.

1) Create a Dynamic Web Project in Eclipse
2) Create the below jsp pages

  •     index.jsp
  •     login.jsp
  •     success.jsp
3) Create the below pages in src folder
  • global.properties
  • LoginAction.properties
  • LoginAction-validation.xml
  • LoginAction.java
  • struts.xml
4) web xml

index.jsp


<html>
<body>
<a href="login.jsp">Click here to view validation demo</a><br>
</body>
</html>

login.jsp

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

<h1>Welcome to Struts2 validation demo</h1>
<s:form action="login">
<s:textfield name="userName" label="UserName" />
<br>
<s:password name="pass" label="Password" />
<br>
<s:submit value="Login" />
<br>
</s:form>
</body>
</html>

success.jsp

<html>
<body>
<h1> Page is validated successfully</h1>
</body>
</html>

global.properties

myapp.login.page.label.username=MyUserName

LoginAction.properties

myapp.login.page.message.username.required=UserName is required
myapp.login.page.message.pass.required=Password is required
myapp.login.page.message.username.invalid=UserName is Invalid

LoginAction-validation.xml

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
       "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
  <field name="userName">
      <field-validator type="requiredstring">
          <message>User Name is required.</message>
      </field-validator>
  </field>
  <field name="pass">
      <field-validator type="requiredstring">
        <message key="myapp.login.page.message.pass.required" />
      </field-validator>
  </field>
</validators>

import com.opensymphony.xwork2.ActionSupport;

LoginAction.java

public class LoginAction extends ActionSupport{

private String userName;
private String pass;
public String getUserName() {
return userName;
}

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

public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}

public String execute() throws Exception {
System.out.println("execute method");
return SUCCESS;
}
}

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" namespace="/" extends="struts-default">
<action name="login" class="LoginAction">
<result>/success.jsp</result>
<result name="input">/login.jsp</result>
</action>
</package>

</struts>


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Struts2Example2</display-name>
    <filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.devMode</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Tuesday 13 August 2013

Top Most Struts 2.x Tags Demo code

This example shows how to use struts 2 tags:

Struts 2 : Check box list
Struts 2: Select
Struts 2: File
Struts 2: Combo Box
Struts 2: Option Transfer Select
Struts 2: Updown Select
Struts 2: Double Select

(All these tags are available in result.jsp)

Struts 2: iterator
Struts 2: If else

(These tags are available in iterator_tag.jsp )

Struts 2:  Dynamic Dispatch

( These tags examples are available in dynamic_dispatch_demo.jsp) 

Struts 2: Action Message

( These tags examples are available in success.jsp) 

1) Create a Dynamic Web Project
2) Create the following jsp pages under WebContent folder
  • index.jsp
  • result.jsp
  • dynamic_dispatch_demo.jsp
  • dispatch_success.jsp
  • dispatch_demo.jsp
  • iterator_tag.jsp
  • success.jsp

3) Create the Action Class in src folder

  • DynamicDispatchAction.java
  • IteratorTagAction.java
  • SaveUserAction.java
  • ShowTagsAction.java
  • UserDispatchAction.java

4) Map the actions and jsp in struts.xml under src folder

  • struts.xml
  • web.xml

index.jsp


<html>
<body>
<a href="showTags">Click here to view tags demo</a><br>
<a href="dispatch_demo.jsp">Click here to view Dispatch Action demo</a><br>
<a href="iteratorTag">Iterator TAG demo</a><br>
</body>
</html>

result.jsp

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

<html>
<body>

<h1>Welcome to Struts2 tags demo</h1>
<s:actionerror />

<s:form action="saveMyUser">
<s:textfield name="userName" label="UserName" />
<br>
<s:password name="password" label="Password" />
<br>
<s:textarea name="address" label="Address" />
<br>
<s:radio name="status" label="Status" list="{'Approved','UnApproved'}" />
<br>

<s:radio name="country" label="Country" list="countries"
value="{'UK'}" />
<br>

<s:checkboxlist list="countries" name="countryCheck"
label="CountrWithCheckbox" value="{'USA','Srilanka'}"></s:checkboxlist>
<s:label name="hello" value="Hello How are you"></s:label>

<s:select list="countries" name="countrySelect"
label="CountryWithSelectBox"></s:select>
<br>



<s:file name="myFIle" label="SelectFile"></s:file>

<s:combobox list="countries" name="comboBox"
label="CountryWithComboBox"></s:combobox>

<s:optiontransferselect label="Employee Records"
name="leftSideEmployeeRecords" leftTitle="LeftSide"
rightTitle="selected employees"
list="{'Deepak Kumar', 'Sushil Kumar','Vinod Kumar','Deepak Monthy',
 'Deepak Mihanti', 'Sushil Kumar', 'Ravi Kant Kumar'}"
headerKey="headerKey" headerValue="--- Please Select ---"
doubleName="rightSideEmployeeRecords"
doubleList="{'Amar Deep Patel', 'Amit Kumar','Chandan Kumar', 
  'Noor Kumar','Tammana Kumari'}"
doubleHeaderKey="doubleHeaderKey"
doubleHeaderValue="--- Please Select ---" />

<s:updownselect
list="#{'01':'January','02':'February','03':'March','04':'April','05':'May','06':'June','07':'July','08':'August','09':'September','10':'October','11':'November','12':'December'}"
name="daysname" headerKey="1" headerValue="-- Please Select --"
moveUpLabel="Move Up" moveDownLabel="Move Down"
selectAllLabel="Select All" />

<s:doubleselect label="Select Item"
headerValue="--- Please Select ---" headerKey="1"
list="{'Color','Fruits','items'}" doubleName="dishes"
doubleList="top == 'Color' ? {'Black','Green','White',
 'Yellow','Red','Pink'} : (top == 'Fruits' ? { 'Apple','Banana','Grapes','Mango'}: {'pen','laptop','mobile'})" />


<s:submit value="SaveUser"></s:submit>
</s:form>

</body>
</html>

dispatch_demo.jsp

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

<s:form action="saveUser">
<s:submit value="SaveUser"/>
</s:form> 

<s:form action="updateUser">
<s:submit value="UpdateUser"/>
</s:form> 

<s:form action="deleteUser">
<s:submit value="DeleteUser"/>
</s:form> 

<s:form action="listUser">
<s:submit value="ListUser"/>
</s:form> 
</body>
</html>

dynamic_dispatch_demo.jsp

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

<s:form action="saveUser">
<s:submit value="SaveUser"/>
</s:form> 

<s:form action="updateUser">
<s:submit value="UpdateUser"/>
</s:form> 

<s:form action="deleteUser">
<s:submit value="DeleteUser"/>
</s:form> 

<s:form action="listUser">
<s:submit value="ListUser"/>
</s:form> 
</body>
</html>


dispatch_success.jsp

<html>
<body>

<h1>Request is dispatched successfully</h1>
</body>
</html>

success.jsp

<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<body>
<h1> Data is saved successfully</h1>
<s:actionmessage/>
</body>
</html>

ShowTagsAction.java

import java.util.ArrayList;
import java.util.List;

public class ShowTagsAction {
List<String> countries;
List<User> userList;

public List<User> getUserList() {
return userList;
}

public void setUserList(List<User> userList) {
this.userList = userList;
}

public String execute() throws Exception {
countries = new ArrayList<String>();

countries.add("India");
countries.add("USA");
countries.add("UK");
countries.add("Kanada");
countries.add("Srilanka");

return "success";
}

public List<String> getCountries() {
return countries;
}

public void setCountries(List<String> countries) {
this.countries = countries;
}
}

UserDispatchAction.java


public class UserDispatchAction {

public String save(){
System.out.println("save method of DispatchAction ");
return "success";
}
public String delete(){
System.out.println("delete method of DispatchAction ");
return "success";
}
public String update(){
System.out.println("update method of DispatchAction ");
return "success";
}
public String list(){
System.out.println("list method of DispatchAction ");
return "success";
}
}

DynamicDispatchAction.java


public class DynamicDispatchAction {

public String save(){
System.out.println("save method of DispatchAction ");
return "success";
}
public String delete(){
System.out.println("delete method of DispatchAction ");
return "success";
}
public String update(){
System.out.println("update method of DispatchAction ");
return "success";
}
public String list(){
System.out.println("list method of DispatchAction ");
return "success";
}
}

SaveUserAction.java

import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
public class SaveUserAction extends ActionSupport{

private String userName;
private String password;
private String address;
List<String> countries;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String execute() throws Exception {
System.out.println("UserName = "+userName);
System.out.println("Password = "+password);
System.out.println("Address = "+address);
if(userName.equals(password)){
List<String> messages = new ArrayList<String>();
messages.add("Data sent to DB");
setActionMessages(messages);
return "success";
}else{
List<String> errors = new ArrayList<String>();
errors.add("Data is invalid");
setActionErrors(errors);
countries = new ArrayList<String>();
countries.add("India");
countries.add("USA");
countries.add("UK");
countries.add("Kanada");
countries.add("Srilanka");
return "input";
}
}

public List<String> getCountries() {
return countries;
}
public void setCountries(List<String> countries) {
this.countries = countries;
}
}

IteratorTagAction.java

import java.util.ArrayList;
import java.util.List;
public class IteratorTagAction {
List<String> countries;
List<User> userList;
public String execute() throws Exception {
countries = new ArrayList<String>();
countries.add("India");
countries.add("USA");
countries.add("UK");
countries.add("Canada");
countries.add("Srilanka");
userList = new ArrayList<User>();
User user = new User();
user.setFirstName("Venkata");
user.setLastName("reddy");
user.setUserName("vreddy");
user.setSalary(400);
userList.add(user);
user = new User();
user.setFirstName("Ram");
user.setLastName("Mohan");
user.setUserName("rmohan");
user.setSalary(500);
userList.add(user);
user = new User();
user.setFirstName("Amod");
user.setLastName("Mudholkar");
user.setUserName("aamod");
user.setSalary(600);
userList.add(user);
return "success";
}

public List<String> getCountries() {
return countries;
}

public void setCountries(List<String> countries) {
this.countries = countries;
}

public List<User> getUserList() {
return userList;
}

public void setUserList(List<User> userList) {
this.userList = userList;
}
}

class User{
private Integer salary;
private String firstName;
private String lastName;
private String userName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
}

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" namespace="/" extends="struts-default">

    <action name="showTags" class="ShowTagsAction">
    <result>/result.jsp</result>
    </action>
   
    <action name="saveMyUser" class="SaveUserAction">
    <result>/success.jsp</result>
    <result name="input">/result.jsp</result>
    </action>
        
        <action name="saveUser" class="UserDispatchAction" method="save">
        <result>/dispatch_success.jsp</result>
        </action>
        
        <action name="updateUser" class="UserDispatchAction" method="update">
        <result>/dispatch_success.jsp</result>
        </action>
        
        <action name="deleteUser" class="UserDispatchAction" method="delete">
        <result>/dispatch_success.jsp</result>
        </action>
        
        <action name="listUser" class="UserDispatchAction" method="list">
        <result>/dispatch_success.jsp</result>
        </action>
        <action name="iteratorTag" class="IteratorTagAction">
        <result>/iterator_tag.jsp</result>
        </action>
    </package>

   

</struts>


web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Struts2Example2</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>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Struts Validations Example                               Struts 2: XML Validation Demo

Monday 12 August 2013

Top Most Some important Facts in Struts 2.0 Framework


Some important Facts in  Struts 2.0 Framework
1) Struts controller (DispatcherFilter,ActionServlet) uses the Command Design Pattern,Action classes use Adapter Design Pattern and process() method of the RequestProcessor uses the Template Method Design Pattern.
2) MVC is the main pattern behind struts development. JSPs are used for view and then there is controller (Front controller Pattern) and then there is model.
3) Struts uses ValueObject pattern also as we normally encapsulate all the data in an object and then pass it to JSPs.
Struts also implement the following J2EE design patterns.

* Service to Worker
* Dispatcher View
* Composite View (Struts Tiles)
* Front Controller
* View Helper
* Synchronizer Token

Is it Inversion of Control ???

If yes, how does inversion of control happen in struts 2.0?

I have heard that this concept is used in Spring but not sure if it is in struts.


Struts2 is based on WebWork which has IoC. Struts2 supports interface injection (IOC).
1) In this article we will talk about the new features in Struts 2.0. Over the years, every developers believes that struts is the best and simple framework to implement. Since last two years, more new frameworks come to the market and the use of Struts is declined. Lack of updation in the Struts framework is the main reason for developers choosing alternative framework. To answer this, Struts team comes with the Struts 2.0, an integration of Struts 1.0 with Webwork. Here we will look into the prominent features in the new framework.
Action classes
2) An Struts 2 Action may implement an Action interface, along with other interfaces to enable optional and custom services. Struts 2 provides a base ActionSupport class to implement commonly used interfaces. Albeit, the Action interface is not required. Any POJO object with a execute signature can be used as an Struts 2 Action object.
Threading Model
3) Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues. (In practice, servlet containers generate many throw-away objects per request, and one more object does not impose a performance penalty or impact garbage collection.)
Testability
4) Struts 2 Actions can be tested by instantiating the Action, setting properties, and invoking methods. Dependency Injection support also makes testing simpler.
Servlet Dependency
5) Struts 2 Actions are not coupled to a container. Most often the servlet contexts are represented as simple Maps, allowing Actions to be tested in isolation. Struts 2 Actions can still access the original request and response, if required. However, other architectural elements reduce or eliminate the need to access the HttpServetRequest or HttpServletResponse directly.
Harvesting Input
6) Struts 2 uses Action properties as input properties, eliminating the need for a second input object. Input properties may be rich object types which may have their own properties. The Action properties can can be accessed from the web page via the taglibs. Struts 2 also supports the ActionForm pattern, as well as POJO form objects and POJO Actions. Rich object types, including business or domain objects, can be used as input/output objects. The ModelDriven feature simplifies taglb references to POJO input objects.
Expression Language
7) Struts 2 can use JSTL, but the framework also supports a more powerful and flexible expression language called "Object Graph Notation Language" (OGNL).
Binding values into views
8) Struts 2 uses a "ValueStack" technology so that the taglibs can access values without coupling your view to the object type it is rendering. The ValueStack strategy allows reuse of views across a range of types which may have the same property name but different property types.
Type Conversion
9) Struts 2 uses OGNL for type conversion. The framework includes converters for basic and common object types and primitives.
Validation
10) Struts 2 supports manual validation via the validate method and the XWork Validation framework. The Xwork Validation Framework supports chaining validation into sub-properties using the validations defined for the properties class type and the validation context.
Control Of Action Execution
11) Struts 2 supports creating different lifecycles on a per Action basis via Interceptor Stacks. Custom stacks can be created and used with different Actions, as needed.

Top Most Struts 2.0 Introduction and Validations using Annotations


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 WebWorkand 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 ActionClass 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 Struts2FilterServletwhich 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-processingand Post-processing functionality for a Request or a Response object in a Web Application. For general information about Interceptors, readers can go through thissection 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 nameattribute 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 Actionclass 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 Actionclass 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 Mappingsdefined 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>
               

4) Struts.xml Configuration File

All the Configuration Related Information are externalized from a Web Application by maintaining them in a Xml File. The new Struts 2.0 Configuration Xml File is very Simple and Modular when compared with its older versions. Let us look into the structure of the Struts 2.0 Configuration File and the Core Elements within them in detail in the following sections.

4.1) Modularization of Configuration Files

The first nice feature is the File Inclusion Faciltity. Assume that in a very complex Web Application, there are multiple modules and each module is designated to be developed by a particular team. Similar to the Modularization of Work, the configuration file can also be made modular using the File Inclusion Facility. For the sake of simplicity, let the assume that there are three modules namely "admin", "customer", "employer" in a Web Application. We can define the three modules in three different Configuration Files, and using the File Inclusion Facility, the three files can be directly included in the Main Configuration File. A Main Configuration File is nothing but a File that includes other Configuration Files. Examine the following code snippet,
Admin-Config.xml
                                      
<struts>
    <!-- Configuration Information Related to Admin Module -->
</struts>
                                      
Customer-Config.xml
                                      
<struts>
    <!-- Configuration Information Related to Customer Module -->
</struts>
                                      
Employee-Config.xml
                                      
<struts>
    <!-- Configuration Information Related to Employee Module -->
</struts>
                                      
All the above separate Configuration Files can be directly referenced or included in the Root Configuration File with the help of <include> tag like the following,
Struts.xml
                                      
<struts>
 
    <!-- Other information goes here -->       
    <include file = "Admin-Config.xml"/>
    <include file = "Customer-Config.xml"/>
    <include file = "Employer-Config.xml"/>   
    <!-- Other information goes here -->
        
</struts>
                                      

4.2) Grouping of Similar Actions inside a Package

Packages in Java are logically used to group similar Classes or Interfaces. Similary, there is a <package> tag in Struts 2.0, which is used to Group Similar Actions along with Interceptors, Results, Exceptions etc. Following is the structure of the packageelement,
Struts.xml
                                      
<struts>
 
    <package name = "MyPackage1">
               
        <interceptors>
        </interceptors>
 
        <global-results>
        <global-results>
 
        <action name = "MyAction1">
        </action>
 
        <action name = "MyAction2">
        </action>
        
    </package>
 
    <package name = "MyPackage2">
               
        <interceptors>
        </interceptors>
 
        <global-results>
            <result name = "common-error">
                /myApp/commons/commonError.jsp
            </result>
        <global-results>
 
        <action name = "MyAction3">
            <result name = "result1">
                /myApp/myResult1.jsp
            </result>
        </action>
 
        <action name = "MyAction4">
        </action>
        
    </package>
 
</stuts>
                                      
Assuming that MyAction1 and MyAction2 are someway related, they are grouped under a package called MyPackage1. All the declaration of Interceptors, Results and Exceptionswithin the Package MyPackage1 will be availabe only within the actions MyAction1 and MyAction2. Similarly all the definition of the Interceptors, Results and Exceptions within the package MyPackage2will be applicable only for MyAction3 and MyAction4action elements. Packages can also be extended through the means of extends attribute like the following,
Struts.xml
                                      
<struts>
    ...
    <package name = "MySubPackage" extends = "MyBasePackage">
        ...                    
    </package>
    ...
</struts>
                                      
Let us define what a Package Extension is and their advantages. Assume that there is a Package called P1 with interceptors I1and I2, Results R1 and R2 and ExceptionsE1 and E2. If we say some Package called P2extends P1, then all the elements that are available in P1becomes visible to Package P2. Package Extension is very similar to Class Inheritance which we normally see in any kind of Object Oriented Language.

4.3) Interceptors and Stack

As previously discussed, Custom Interceptors can be written and made immediately available in Application by configuring them in the Configuration File with the help of <interceptor> tag. An Interceptor defined can be applied to a particlur Action (or a set of Actions) through the help of <intercept-ref> tag. Following Xml snippet will show this,
Struts.xml
                                      
<struts>
 
    <package name = "MyPackage">
        
        <interceptors>
            <interceptor name="logger-interceptor"
                class="myinterceptors.LoggingInterceptor">           
        </interceptor>
        
        <action name = "MyAction">
            <result name = "MyResult">
                /myApp/Result1.jsp
            </result>
            <interceptor-ref name = "logger-interceptor"/>
        </action>
 
    </package>
 
</struts>
                                      
The above code defines an Interceptor called logger-interceptor identified by the class myinterceptors.LoggingInterceptor and the same is included for an action called MyAction with the help of <interceptor-ref>tag. It is very common that a Set of Interceptors (often called Interceptor Stack) to be applied as a whole for one or more actions. Such a piece of functionality can be easily achieved with the help of <interceptor-stack>element.
struts.xml
                                      
<struts>
 
    <package name = "MyPackage">
 
        <interceptors>
            <!--Some set of common interceptors for a particular action-->
            <interceptor name = "A_I1" class = "MyA_I1">
            <interceptor name = "A_I2" class = "MyA_I2">
            <interceptor name = "A_I3" class = "MyA_I3">
            <interceptor name = "A_I4" class = "MyA_I4">
 
            <!--Another set of common interceptors  -->
            <interceptor name = "B_I1" class = "MyB_I1">
            <interceptor name = "B_I2" class = "MyB_I2">
            <interceptor name = "B_I3" class = "MyB_I3">
            <interceptor name = "B_I4" class = "MyB_I4">
        </interceptors>
 
        <interceptor-stack name = "A">
            <interceptor-ref name = "A_I1">
            <interceptor-ref name = "A_I2">
            <interceptor-ref name = "A_I3">
            <interceptor-ref name = "A_I4">
        </interceptor-stack>
        
        <interceptor-stack name = "B">
            <interceptor-ref name = "B_I1">
            <interceptor-ref name = "B_I2">
            <interceptor-ref name = "B_I3">
            <interceptor-ref name = "B_I4">
        </interceptor-stack>
 
        <action name = "MyAction1">
            <interceptor-ref name = "A"/>
        </action>
 
        <action name = "MyAction2">
            <interceptor-ref name = "B"/>
        </action>
 
        </package>
 
</struts>
                                      
The above Xml snippet defines a series of interceptors with the help of <interceptors>tag. Related Set of Interceptors to be added to an action element is then categorized with the help of <interceptor-stack>element. The categorized Interceptor Stack is then bound to an action element using the same sensible <interceptor-ref> tag. The framework is sensible here, it will find out the value for the nameattribute. If the value is an interceptor name, then the corresponding intercept() method will be invoked, else if the value is an Interceptor-Stack, then all the interceptors within the stack are iterated in the same order as their definition and their intercept()method will be invoked.

5) Validation using Configuration Files and Annotations

Struts 2.0 comes with new set of Robust Validation Features. Most of the common Validation Activities related to a Web Application are taken care by the Framework itself which means that only less burden lies on the shoulders of a Developer. Following lists the most commonly used Validations in Struts 2.0,
  1. Integer Validation - Checks whether the value for a field is an integer and it falls within the integer range.
  2. Double Validation - Checks whether the value for a field is a double and it falls within the double range.
  3. Date Validation - Checks whether the value of the field is a Date value.
  4. Email Validation - Validates whether the input string is in appropriate email format (Eg: userName@someDomain.com).
  5. Url Validation - Ensures whether the value for a field is in appropriate URL Format.
  6. Required Validation - Checks for the emptiness of a field value.
  7. Required String Validation - Checks for the emptiness of a trimmed String value (not null)
  8. String Length Validation - Checks whether the given field value is of the specified length.
  9. Regex Validation - Ensures whether the field Value given matches the Regular Expression.

5.1) Validations Types based on Scope

Validation comes in two different flavors based on its Scope. A Scope defines whether a Validation is dedicated to a Single Field in a Page or it corresponds to a particular Action which may involve more than one fields along with some other constraints. Based on this, the following types are available.
  • Field Validation
  • Non-Field Validation
5.1.1) Field Validation
Validating a Field in a Page for correctness is a common situation for almost any Web Application. As mentioned this type of Validation is restricted to a particular field. Common cases may be validating the username and password field for emptiness. Both Xml-Based Validation or Annotation-Based Validation can be mentioned for the field elements. The following snippet code is an example of Field-Level Validation.
validation.xml
                                      
<field name="username">
    <field-validator type="required">
        <message>User name cannot be empty.</message>
    </field-validator>
<field-name="username">
                                      
<field name="email_address">
    <field-validator type="required">
        <message>Email Address cannot be empty.</message>
    </field-validator>
 
    <field-validator type="email">
        <message>
            Enter the email id in proper format (eg: abc.def@xyz.com)
        </message>
    </field-validator>
</field>
                                      
The above Xml snippet essentially applies one Validation Rule to the username field and two Validation Rules to the email-address field. The type of the validation rule is specified by the attribute called type. In our case, the types represent the Required Validation (required)and the EMail Validation (email). Any number of validation rules can be attached to a field element with the help of <field-validator>tag.
Annotation-Based Validationfor a field is also possible. The only requirement for the class is that the class that contains the fields representing the page (it can be an Action class too) must be marked with the @Validation annotation. Assume the Validation has to take place when the user submits the form. It is known that the Action.execute() method will be invoked as a result of this. So we can perform the field validations by marking the necessary Annotations against the method.
MyAction.java
                                      
package myactions;
 
import com.opensymphony.xwork2.validator.annotations.*;
 
@Validation
public class MyAction{
    
    @Validations(
        emails = {              
        @EmailValidator(type = ValidatorType.SIMPLE, 
        fieldName = "email_address", 
        message = "Enter the email id in proper format (eg: abc.def@xyz.com)")
        } 
               
        requiredFields = {
        @RequiredFieldValidator(type = ValidatorType.SIMPLE, 
        fieldName = "email_address", 
        message = "Email Address cannot be empty.")},
               
        @RequiredFieldValidator(type = ValidatorType.SIMPLE, 
        fieldName = "username", 
        message = "User name cannot be empty.")}             
        }              
    )
    public String execute(){
        // Other Logic goes here..  
    }
               
}
                                      
Instead of marking the whole Bunch of Validations on the Action.execute method(), there is another alternate way wherein which the Annotation-Based Validation can be applied on a Field-by-Field basis. Assume that username and password are the two properties inside the Action class, then the following type of Annotation is also possible.
MyAction.java
                                      
package myactions;
 
import com.opensymphony.xwork2.validator.annotations.*;
 
public class MyAction{
 
    private String username;
    private String emailAddress;
        
    @RequiredFieldValidator(type = ValidatorType.SIMPLE, 
        fieldName = "username", 
        message = "User name cannot be empty.")      
    public String getUsername(){
        return username;
    }
        
    ...
        
    @RequiredFieldValidator(type = ValidatorType.SIMPLE, 
        fieldName = "email_address", 
        message = "Email Address cannot be empty.")  
    @EmailValidator(type = ValidatorType.SIMPLE, 
        fieldName = "email_address", 
        message = "Enter the email id in app. format(eg: abc.def@xyz.com)") 
    public String getEmailAddress(){
        return emailAddress;
    }   
}
                                      
5.1.2) Non-Field Validation
Non-Field Validationsare generally Application specific and they will be given implementation by the Application Developers. Example may be performing validations based one or more fields in a form along with some Application specific Business Logic. The only availabe Validation that comes along with Struts 2.0 in this category is the Expression Validation. Assume that in some Application an Employee is asked to enter his Dirth of Birth and the Joining Date. For sure, the Birth Date will be logically lesser than the Joining Date. We can enforce this kind of Validation Rule using Expression Validationas follows.
validation.xml
                                      
<field name = "date_of_birth">
</field>
 
<field name = "joining_date">     
</field>
                                              
<validator type = "expression">
    <param name="expression">
        date_of_birth lt joining_date
    </param>
    <message>
        Warning: DOB(${date_of_birth}) is greater than Joining Date(${joining_date})
    </message>
</validator>
                                      
The first noticeable thing in the above Xml snippet is that the type of the Validation is identified as expression. The param tag is used to specify the constraint to be applied for the Validation. Here the constraint is very simple which tells that the Date of Birth for an Employee must be lesser that his Joining Date in the Organisation. Also notice, how actually the value of the field is taken to display error messages ($field_name). If the user enters 10/10/2000 for the DOB field and 10/10/1960 in the Joining Date Field, then the message "Warning: DOB(10/10/2000) is greater than the Joining Date(10/10/1960)" will be flashed in the User Browser.

5.2) Validation Types based on Implementation

If we look at another angle based on how Validations are Configured or Implemented, they can be classified into two categories namely,
  • Declarative Validation
  • Programmtic Validation.
5.2.1) Declarative Validation
If the Validation Logic for a particular Field or for an Entire Action is specified either in the Xml File or through Annotations, then it is called Declarative Validation. Whatever Validation we are seeing till now are Declarative Validations only. The idea behind Declarative Validation is that during the Deployment time of the Web Application itself, the Framework or the Container will be in a suitable position to mapthe set of fields participating in Validations against their Validation Rules.
5.2.2) Programmatic Validation
Not at all times, the Built-in Validations provided by the Framework will be sufficient. At times, there will be a situation to perform a Complex Validation Logic that is very specific to an application. For example situation may occur wherein, a single value of a field can be validated based on the content of some other text-fields along with some values fetched from the Database. In such a case, we can implement the Validation Logic directly into the Code. The following code snippet shows that,
MyAction.java
                                      
package myactions;
 
import com.opensymphony.xwork2.*;
 
public class MyAction extends ActionSupport{
    
    public void validate(){    
        String stockSymbol = getStockFieldValue();
               
        if ((stockSymbol == null) || (stockSymbol.trim().length == 0) ){
            addFieldError("stock_field", "Stock Symbol cannot be empty"); 
        }
               
        boolean result = validateStockSymbolFromDb(stockSymbol);
        if (!result){
            addActionError("Invalid Stock Symbol");
        }
        // Other Code goes here.
    }
}
                                      
If an Application is going to provide Manual Validation, then it has to implement two interfaces namely Validateable and ValidationAware interfaces in the com.opensymphony.xwork2 package. The core logic for the Custom Validation must be done within the Validateable.validate() method. ValidationAware Interface is used to collect the Error Messagesthat are related to fields or to a general Action. Fortunately, as expected, Struts 2.0 provides Default Implementation for both these interfaces in the ActionSupport class. So it is wise to extend this class for performing any Validation Logic without redefining every methods available in the Validation Interfaces.
Our sample Action class extends ActionSupport class to get all the Basic functionality for Storing and Retrieving Error Messages. Two types of Error Messages are available in the ValidationAware interface. One is the Field-level Messages and the other thing is the Action-Level Messages. Convinient methods are available for populating and retreiving both these messages. Methods addActionError(String message)and addFieldMessage(String fieldName, String message) are used to populate the error messages to an internal Collection. To retrive the Error Messages getActionErrors() and getFieldErrors() are used. To check whether errors have occured in a page use hasActionErrors() and hasFieldErrors() methods.
The sample code essentially checks the value of the stock symbol obtained from the field and checks for its emptiness. If not, it is populating the field-level error message by calling the addFieldMessage("..."). It then make Database Calls to ensure whether the Stock Symbol is valid. If not, an Action Level Error message is populated in the code by calling addActionEror("...");

LinkWithin

Related Posts Plugin for WordPress, Blogger...

Labels

Core Java programming core java interview question Core Java Faq's Servlets coding database jsp-servlet spring Java linux unix interview questions java investment bank Web Services Interview investment bank mysql Senior java developer interviews best practices java collection tutorial RMI SQL Eclipse FIX protocol tutorial tibco J2EE groovy java questions SCJP grails java 5 tutorial jdbc beginner error and exception Design Patterns Java Programming Tutorials fundamentals general object oriented programming xml Java Programs Hibernate Examples Flex JAMon Java xml tutorial logging Jsp Struts 2.0 Sybase and SQL Server debugging java interviews performance FIX Protocol interview questions JUnit testing WebSphere date and time tutorial experienced java IO tutorial java concurrency thread Ejb Freshers Papers IT Management Java Exapmle Java Script SQL and database tutorial examples Scwcd ant tutorials concurrency example and tutorial future state homework java changes java threading tricky Agile Business of IT Development JSTL Java JSON tutorial Java multithreading Tutorials PM Scrum data structure and algorithm java puzzles java tips testing tips windows 8 5 way to create Singleton Object Architect Interview Questions and Answers Architecture Architecure Bluetooth server as swing application that searches bluetooth device in 10 meter circle and show all devices. You can send file to any bluetooth device. C Programming CIO Callable Statement in Java Circular dependency of Objects in Java Comparable Example in Collection Custom annotation in Java Developer Interview Divide and rule example in java Drupal Example of Singleton Pattern FIX protocol ForkJoin Example in Java 7 Get data from dynamic table with Java Script Git HTML and JavaScript Health Hello World TCP Client Server Networking Program Hibernate Basics Hibernate Interview Question Answer J2EE Interview Question And Answers J2ME GUI Program JEE Interview QA JMS interview question Java J2EE Hibernate Spring Struts Interview Question Java System Property Java Threads Manager Portlets Provident Fund Read data from any file in same location and give the required result. Reading Properties File in Java Redpoint Rest WebService Client Rest Webservice Test SAL join with ven diagram SCP UNIX COMMAND SSL Singleton Pattern in Java Spring Bean Initialization methods and their order Spring Interview Questions Struts Struts 2.0 Basics Struts 2.0 Design Pattern Submit Html Form With Java Script On The Fly Unix executable For Java Program XOM DOM SAX XP books computers core java; core java; object oriented programming data structure; java investment bank; design pattern dtd duplicate rows in table get browser name with jquery grails podcast inner class java beginners tutorial java cache java networking tutorial java spring java util; java collections; java questions java.java1.5 linked list mailto function with all browser oracle database oracle duplicate rows orm schema social spring mvc questions struts transaction tricks tweet windows xslt