Professional Documents
Culture Documents
Stuts PDF
Stuts PDF
Article
Home> Articles > JSP > Fundamentals
Struts Tutorial
The JSP Struts Tutorial will help new JSP developers understand the benefits of struts and how to program their first
struts program. Also included are JSP Struts movies to learn Struts by example. Struts source code is also included for
download. This is Part 1 of a 3 Part Struts tutorial. See the left hand menu for the other parts when you finish this part of
the Struts tutorial.
1/121
01/14/11 00:22:21
What is Struts?
Struts is a popular open source framework from Apache Software Foundation to build web applications that integrate with
standard technologies such as Servlets, Java Beans and Java Server pages.
Struts offers many benefits to the web application developer,including the Model-View-Controller (MVC) design patterns
(best practice) in web applications.
The Model-View-Controller paradigm applied to web applications lets you separately display code (for example, HTML
and tag libraries) from flow control logic (action classes) from the data model to be displayed and updated by the
application.
Struts offers a set of tag libraries to support the faster development of the different layers of the web application.
The basic idea of the MVC architecture is to divide the application into three layers: Model that represents the data layer,
a view layer that represents the data processed by the model component; and a Controller component that is responsible
for interaction between the model and the controller.
So when we say Struts is an MVC framework for web based applications, we actually mean that it facilitates the rapid
development of applications by providing a Controller that helps interaction between the model and the view so that an
application developer has not to worry about how to make view and the model independent of each other and yet exist in
coordination.
Struts is basically a Controller. It depends on other things for the model and the view. It can communicate with Hibernate,
Enterprise Java Beans or any other java components for the model. JSP/Servlets are used for the view which use html
2/121
01/14/11 00:22:21
front end internally. Struts provides several tag libraries to support the rapid development for the view layer.
3/121
01/14/11 00:22:21
Why do we need Struts?
Although a dynamic web application can be developed using JSP and Servlet technology, there are many problems.
To solve these problems,we need a mechanism that can separate the presentation layer of a web application from business
logic. Luckily we have MVC and we have Struts. MVC is a design pattern (best practice method) that separates the
application design into there main parts:
4/121
01/14/11 00:22:21
Advantages of Struts
Struts offers many advantages to the application programmer while reducing the development time and making the
manageability of the application easier. Here are few key advantages of using Struts instead of managing the every layer
of the web application yourself.
Rather than hard coding information into java programs,many Struts values are represented in XML or property files. This
loose coupling means that many changes can be made without modifying or recompiling Java code,and that wholesale
changes can be made by editing a single file. This approach also lets Java and Web developers focus on their specific
tasks (implementing business logic,presenting certain values to clients,etc.) without needing to know about the overall
system layout.
Form Beans
In JSP,you can use property=* with jsp:setProperty to automatically populate a JavaBean component based on incoming
request parameters. Unfortunately,however,in the standard API this capability is unavailable to servlets,even though with
MVC it is really servlets,not JSP pages,that should usually be the target of form submissions. Apache Struts extends this
capability to Java code and adds in several useful utilities,all of which serve to greatly simplify the processing of request
parameters.
Bean Tags
Apache Struts provides a set of custom JSP tags (bean:write,in particular) that let you easily output the properties of
JavaBeans components. Basically,these are concise and powerful variations of the standard jsp:useBean and
jsp:getProperty tags.
HTML tags
Apache Struts provides a set of custom JSP tags to create HTML forms that are associated with JavaBeans components.
This bean/form association serves two useful purposes:
o It lets you redisplay forms with some or all previously entered values intact.
Apache Struts has built-in capabilities for checking that form values are in the required format. If values are missing or in
an improper format,the form can be automatically redisplayed with error messages and with the previously entered values
maintained.
This validation can be performed on the server (in Java),or both on the server and on the client (in JavaScript).
Struts 2.0 is currently in beta phase and contains the existing Struts features plus all the features of WebWorks framework.
5/121
01/14/11 00:22:21
6/121
01/14/11 00:22:21
1. Eclipse does not come with a bundled Java Development Kit. Download and install JDK 1.4 (Sun or IBM)
http://java.sun.com/j2se/downloads/index.html
http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.2.1-200609210945/eclipse-SDK-3.2.1-win32
3. By default,Eclipse supports only basic Java Development. Most of the advanced features are available in the form of
pluggins which may be downloaded and installed from there respective repositories. MyEclipse is a mini-IDE which is
installed as an add-on to the Eclipse. Download and install MyEclipse 5.1 from:
http://www.myeclipseide.com/Downloads%2Bindex-req-viewsdownload-sid-15.html
4. To deploy the web applications,we need a Servlet container like tomcat or JBoss. Download and install Tomcat 5.0.x
(or other compliant Servlet/EJB container) from
http://www.axint.net/apache/jakarta/tomcat-5/v5.0.28/bin/jakarta-tomcat-5.0.28.exe
If your Eclipse version is other than 3.2.1,please download an appropriate MyEclipse plug-in from
http://www.myeclipseide.com/
7/121
01/14/11 00:22:21
Let us consider an example – a web based user registration application. Usually every web based application requires
secure login to access its critical resources therefore a user management is part of every web application.
Our first Struts application is a web based user registration application. The application is capable of displaying the list of
registered users and allowing the user to add a new user to the database. We’ll use a single table ‘users’ to store the user
information. Select any database of your choice,and create a table USERS with following fields:
first_name text,
last_name text,
age number,
email text,
password text
);
8/121
01/14/11 00:22:21
We are using MyEclipse as a development environment which is an eclipse plugin. Let's create a new project in Eclipse
platform and configure it as shown below.
9/121
01/14/11 00:22:21
Since Microsoft Access does not have a JDBC driver,we’ll connect using the JDBC-ODBC Bridge. Let’s create an ODBC
DSN first. If you are using a database that supports JDBC driver,you don’t need to do this,just replace the connection
URL while connecting to the database in next section.
10/121
01/14/11 00:22:21
We have configured the project for struts. But wait…we are missing something. We still don’t have an application server
ready to deploy our application. Do we have? Let’s configure the eclipse for the application server.
11/121
01/14/11 00:22:21
Struts Configuration
Now that we have configured our project for struts,let’s have a look at the configurations MyEclipse has made for us.
Web.xml
Web.xml resides in application’s WEB-INF directory and contains the essential configuration for the web application like
the Servlet mappings,Authentications mechanisms,Tag libraries etc. Let’s see what is in web.xml right now.
As we can see,there is one Servlet configured and is mapped with URL pattern *.do. What is this ‘ActionServlet’ for?
This is the simple way how the Struts CONTROLER is plugged into the web application.
The basic reason of defining a servlet mapping for a web application is that whenever someone access a page that matches
the URL pattern defined in servlet mapping,Application Server will redirect the request to this servlet. That means,we
have configure Struts Action Servlet to receive all the request that end with a .do keyword. We can even configure it for
.html or .jsp or .abc,.do is the generally accepted token.
Struts-config.xml
<?xml version=1.0 encoding=UTF-8?>
<!DOCTYPE struts-config PUBLIC -//Apache Software Foundation//DTD Struts Configuration 1.2//EN
http://struts.apache.org/dtds/struts-config_1_2.dtd>
<struts-config>
<data-sources />
<form-beans />
<global-exceptions />
12/121
01/14/11 00:22:21
<global-forwards />
<action-mappings />
<message-resources parameter=com.visualbuilder.struts.ApplicationResources />
</struts-config>
We don’t have anything special in this file configured,but as you can see,we have the basic tags. We’ll add the appropriate
struts components to these tags as we develop them. One important thing in this file is the message-resources. This is a
resource bundle that will contain all the errors,labels or other messages that we want to display on the view (jsp pages).
The separation of the String messages from the jsp pages helps internationalization.
13/121
01/14/11 00:22:21
Let’s start with our first java class. Remember we have a table “users” in the database. Let’s write a simple bean that
represents this table.
package com.visualbuilder.struts.beans;
14/121
01/14/11 00:22:21
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
15/121
01/14/11 00:22:21
ResourceManager
As we have already discussed,one of the main concerns of the struts framework is to separate the string resources from the
view. For this purpose,we have already defined a message-resources property n struts-config.xml. Most of the struts
components will expect a property key where a string literal will be needed. To be consistent with the struts
framework,we will try to separate the string resources from our normal java classes where we are not using struts
components. To do this,we can use java.util.ResourceBundle class to pick the values from properties file against the
specified keys. To ease the manipulation of string resources where we are not using the struts components,we’ll write a
separate class.
package com.visualbuilder.struts;
import java.util.ResourceBundle;
16/121
01/14/11 00:22:21
Now let us write our business class that has the ability to perform several actions on the user like adding a new user to the
database,updating an existing user,deleting a user or fetching a user from the database. Let us call this class a
UserManager.
package com.visualbuilder.struts.db;
private UserManager()
{
}
public static UserManager getInstance()
{
if(mgr == null)
{
mgr = new UserManager();
}
return mgr;
}
}
Because for one application,there can exist only a single UserManager,we have made the UserManager a singleton. We will
use UserManager.getInstance() whenever we need an instance of UserManager.
Connecting to a database
The purpose of the UserManager is to provide an interface between the database and the client applications that need
access to the database. Let’s connect to the database and add the following code in the constructor.
17/121
01/14/11 00:22:21
package com.visualbuilder.struts.db;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import com.visualbuilder.struts.ResourceManager;
import com.visualbuilder.struts.beans.User;
private UserManager()
{
String driverClass = ResourceManager.getString(database.driver);
String dbUrl = ResourceManager.getString(database.url);
String dbUser = ResourceManager.getString(database.user);
String dbPassword = ResourceManager.getString(database.password);
try{
Class.forName(driverClass);
con = DriverManager.getConnection(dbUrl,dbUser,dbPassword);
}catch(Exception exp){
System.err.println(Could not connect to dtabase.n exp.getMessage());
}
}
public void saveUser(User user) throws SQLException
{
if(user == null)
throw new SQLException(ResourceManager.getString(save.user.null));
Connection connection = getConnection();
pstmt.executeUpdate();
pstmt.close();
}
public User getUser(String userId) throws SQLException
{
18/121
01/14/11 00:22:21
if(userId == null || userId.length() == 0)
throw new SQLException(ResourceManager.getString(retrieve.user.null));
Connection connection = getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(select * from users where user_id=' userId ');
User user = null;
if(rs.next())
{
user = new User(userId);
user.setFirstName(rs.getString(first_name));
user.setLastName(rs.getString(last_name));
user.setAge(rs.getInt(age));
user.setEmail(rs.getString(email));
}
rs.close();
stmt.close();
return user;
}
public List list() throws SQLException
{
Connection connection = getConnection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(select * from users);
User user = null;
List list = new ArrayList();
while(rs.next())
{
user = new User(rs.getString(user_id));
user.setFirstName(rs.getString(first_name));
user.setLastName(rs.getString(last_name));
user.setAge(rs.getInt(age));
user.setEmail(rs.getString(email));
list.add(user);
}
rs.close();
stmt.close();
return list;
}
private Connection getConnection() throws SQLException
{
if(con == null)
throw new SQLException(ResourceManager.getString(database.notConnected));
return con;
}
public static UserManager getInstance()
{
if(mgr == null)
{
mgr = new UserManager();
}
return mgr;
19/121
01/14/11 00:22:21
}
public void finalize()
{
try{
con.close();
}catch(Exception exp){}
}
}
We have used several properties in this class. Add these properties in the ApplicationResources.properties file.
Now we have all the business functions available,we are ready to move to the formal development of the struts based
application.
20/121
01/14/11 00:22:21
21/121
01/14/11 00:22:21
Adding ActionForward
The forward element in struts-config.xml describes an ActionForward that is to be made available to an Action as a return
value. An ActionForward is referenced by a logical name and encapsulates a URI. A forward element may be used to
describe both global and local ActionForwards. Global forwards are available to all the Action objects in the module.
Local forwards can be nested within an <action> element and only available to an Action object when it is invoked
through that ActionMapping. Let us add two forwards for LoginAction “success” and “fail”. After adding the two
forwards,the <action> tag looks like this:
<action
path=/login
type=com.visualbuilder.struts.action.LoginAction
validate=false>
<forward name=success path=/manageusers.jsp />
<forward name=failure path=/index.jsp />
</action>
Note the two forwards success and the failure. The path attribute in each forward tag is the resource to which the request
will be redirected when forwarded to a particular forward. Let us now program our action to return to “success” if the
entered user id and password is admin/admin. Right now we don’t have any action form associated with this action,let’s
get the parameters from request as we do in servlets.
Now create index.jsp so that we have a form to submit values to this form. Add the following form in the body section of
the jsp.
We are almost ready to run the project. But let’s create a file manageusers.jsp so that if we enter a valid user id /
password,we can see the success page. Add a simple success message “You are logged into this page”.
22/121
01/14/11 00:22:21
23/121
01/14/11 00:22:21
Now its time to test the magic of our first struts application. First step towards this is to deploy the application to the
tomcat server we already configured in this tutorial.
24/121
01/14/11 00:22:21
In our LoginAction,we retrieved the form values using the conventional methods in HttpServletRequest. Struts provides
an easy way to retrieve these values with the help of form beans. A form bean is a simple JavaBean that extends from
org.apache.struts.action.ActionForm. We already have a JavaBean “User” but that does not extend from ActionForm. We
can reuse this JavaBean for this purpose. Let’s add the extends clause to the User class so that the signature of the class
becomes
Also we need to add a no-argument constructor to the User class to enable the struts framework to instantiate the bean.
public User(){
super();
25/121
01/14/11 00:22:21
Adding a form bean is a two step process. First of all we need to declare the form bean in the <form-beans> tag. Then we
can associate this form bean to as many actions as we want. To declare the form bean,add the following line in the
<form-beans> tag.
Now we will associate this form bean with the LoginAction. Update the action tag in action-mappings so that it becomes
like this.
<action
name=loginForm
path=/login
scope=request
type=com.visualbuilder.struts.action.LoginAction
validate=false>
</action>
Now update the LoginAction to retrieve form values from form bean instead of request object though they are still
available in the request object s well. Execute method should look like this now.
Again deploy and run the project. You should get the same behavior as you got earlier.
26/121
01/14/11 00:22:21
The Struts framework provides a set of built-in Tag libraries that allow you to build the view part of the MVC without
embedding Java code directly within your application JSPs. Some commonly used struts tag libraries are described below.
We have already used the ActionForm,but we actually have not enjoyed the blessings of struts. Let’s program our action
to return an appropriate error message called ‘ActionError’ when the user fails to login successfully. Also re-arrange our
view (the index.jsp) to use the struts tag libraries to manipulate the ActionForm values,and display the appropriate error
message on error.
Note that we have created a new ActionMessage with a key “login.failed”. This key must exist in the
ApplicationResources.properties file. Add the following line in the resource file.
27/121
01/14/11 00:22:21
<html:errors/>
<html:form action=/login>
<table border=0>
<tr>
<td>Login:</td>
<td><html:text property=userId /></td>
</tr>
<tr>
<td>Password:</td>
<td><html:text property=password /></td>
</tr>
<tr>
<td colspan=2 align=center><html:submit value=Login/></td>
</tr>
</table>
</html:form>
</body>
</html>
As you can see,we have declared a tag library ‘struts-html.tld’. This is the Html tag library we talked about a while ago.
The tag <html:errors/> is responsible for displaying the message that we may have saved in the request or the session.
We can specify the scope as an attribute to this tag.
Did you notice the field values after submitting the invalid values? Yes! The values again appear in the field when the
error message is displayed. This is particularly important when submitting huge forms. And we have achieved all this
without any extra programming.
28/121
01/14/11 00:22:21
Let us write a simple action and a view that displays the user list on our manageusers.jsp. First of all,create an Action
class named ‘ListAction’ and add the execute method as following.
<body>
<center><h3>User List</h3></center>
<html:errors/>
<logic:present name=list>
<table border=0 cellspacing=0 cellpadding=0 align=center width=70% style=border-collapse:collapse;>
<tr bgcolor=#98AFCC>
<th>User ID</th>
29/121
01/14/11 00:22:21
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
</tr>
<%boolean even = false; %>
<logic:iterate id=user name=list>
<% even = !even; %>
<tr bgcolor=<%=even?#B7D3F5:#D6E0F5 %>>
<td>
<bean:write name=user property=userId />
</td>
<td>
<bean:write name=user property=firstName />
</td>
<td>
<bean:write name=user property=lastName />
</td>
<td>
<bean:write name=user property=email />
</td>
</tr>
</logic:iterate>
<tr>
<td colspan=6 align=center>
<a href=adduser.jsp>Add New User</a>
</td>
</tr>
</table>
</logic:present>
</body>
</html>
Note that in this jsp,we have not performed any loop and still we are iterating over the list. Also note the separation of
view from the model (data).
Now We need to update the ‘success’ forward in struts-config.xml to forward to manageusers.do instead of
manageusers.jsp. Also we need to add the manageusers action entry in the struts-config.xml. Now the <action-mappings>
looks like this.
<action-mappings >
<action
name=loginForm
path=/login
scope=request
type=com.visualbuilder.struts.action.LoginAction
validate=false>
<forward name=failure path=/index.jsp />
30/121
01/14/11 00:22:21
<forward name=success path=/manageusers.do />
</action>
<action path=/manageusers type=com.visualbuilder.struts.action.ManageUsersAction >
<forward name=success path=/manageusers.jsp />
</action>
</action-mappings>
On redeploying and running the application,you should be able to see a list of users on successful login. You don’t have
any data in the database right now,so you might be viewing a page with only one link “Add New User” but if you add few
records manually,you will see the list of users.
The variable even is used to indicate if the current row is even or odd to change the row background.
31/121
01/14/11 00:22:21
Add User Action - New Struts Action Class
Now it’s time to add a new user to the database. Let’s write an action first that can save a user in the database. Create a
new Action class ‘AddUserAction’ and add the following code in its execute method.
<action
attribute=loginForm
name=loginForm
path=/adduser
scope=request
type=com.visualbuilder.struts.action.AddUserAction
validate=false >
<forward name=success path=/manageusers.do />
</action>
Note that we have associated the same form bean that we did when writing the LoginAction.
32/121
01/14/11 00:22:21
Now it is the time to write a view component for our AddUserAction. Create a jsp page ‘adduser.jsp’ with the following
code.
33/121
01/14/11 00:22:21
Run the application,login as admin/admin and click on Add New User link at the bottom of the page. You will find a
form. Enter the appropriate values,and click on submit button. You will again be redirected to the page showing the list of
users and notice that the new user has been added to the list.
34/121
01/14/11 00:22:21
Try to create a user with invalid values. For example an invalid email address that does not follow email addresses rules.
You will see that the system does not check the validity of the data and the user still gets inserted into the database.
To solve this issue,we need to validate the data before inserting into the database or perform any operation on the data.
We have two options to do this.
1. Perform the validation in action class and return to failure if the validation fails.
The first option is not feasible because one form bean may be used in many actions. So we will need to perform validation
in all actions where this form bean is used. The better choice is to perform validation in form bean.
Struts framework provides validation facility for form beans. If we need to perform validation on a form bean,we need to
override validate method in our ActionForm class. The validate method returns an instance of ActionErrors. We can
return ActionErrors instance with appropriate ActionError object if the validation fails,or simply return empty
ActionErrors instance to indicate that the validation has passed and the struts frame may forward the request to action
class. Let’s add the validation to our User class.
if(!getEmail().matches(^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$)){
errors.add(name,new ActionMessage(email.invalid));
}
}
return errors;
}
Also we need to enable the validate=”true” and provide an input attribute in the action configuration in struts-config.xml
<action
attribute=loginForm
name=loginForm
path=/adduser
35/121
01/14/11 00:22:21
scope=request
validate=true
input=/adduser.jsp
type=com.visualbuilder.struts.action.AddUserAction>
<forward name=success path=/manageusers.do />
</action>
Also we have used two error messages if the validation fails. Add these two keys in the ApplicationResources.properties.
Now run the application and try to create a user with empty User ID or invalid email address. You will see the system
does not insert the user into the database.
36/121
01/14/11 00:22:21
After reading this tutorial you should have a good idea of how to write a Struts based web application using Eclipse and
MyEclipse platform.
In addition,we also covered a lot more concepts of what actually the MyEclipse did and how to do them manually even if
we don't have a sophisticated IDE.
After completing this tutorial,with just a few required libraries,a Standard Java Development Kit and an appropriate
installation of Tomcat,you should be able to develop and deploy a struts based application.
The approach used in this tutorial was using a 'registration' application as a case study.
What next?
JSP Tutorial
Hibernate Tutorial
Java Tutorial
If you would like to discuss the topics or be kept up to date then sign up to the following groups and edit your email
update settings in your groups area in your profile. We will then notify you of updates.
JSP Group
37/121
01/14/11 00:22:21
Java Group
38/121
01/14/11 00:22:21
Introduction
This tutorial will help you to learn many features available with the struts framework. You will see how useful are
DynaActionForm and DispatchAction classes in struts framework.
The tutorial helps you to understand the Validation framework and its usefulness. You will see how the validation
framework can be used for both server side and client side validations with less effort. This tutorial also helps you to
understand how struts solves the the real life problem of duplicate form submission through its token mechanism.
Further this tutorial will help you to understand the exception handling mechanism available with the struts framework
and how do we create our own exception handlers in struts. Struts also provide the plug-in mechanism for creating the
custom plug-in for the application. This tutorial will also guide you how to create the plug-in for the application in struts.
39/121
01/14/11 00:22:21
DispatchAction
The major component in the Struts based application is the Action class. Action class only defines the next steps and logic
processing for the application. The execute() method is called by the framework for the processing. All the business logic
and all the flow is derived from the execute() method in the Action class. There is a special Action class which will permit
the user to have more than one method which can be called by the framework and not just the execute() method. This class
is DispatchAction. The class is helpful to have all the methods related to a single UI page in one Action class and
developers need not to implement the logics in different classes. The method to be called on Action is decided with the
parameter attribute in the <action> tag of struts-config.xml. The code for the mapping is given below.
<action path=/dispatchActionExample
type=com.visualbuilder.DispatchActionExample
parameter=method
name=inputForm
input=/index.jsp />
Note:-The above mapping will check the method parameter and call the method with the name coming in the parameter.
Add the following keys in the messageresources.properties file under WEB-INF/classes
40/121
01/14/11 00:22:21
<action path=/dispatchActionExample
type=com.visualbuilder.DispatchActionExample
parameter=method
name=inputForm
input=/index.jsp />
</action-mappings>
<!-- ======================================== Message Resources Definitions -->
<message-resources parameter=MessageResources />
</struts-config>
41/121
01/14/11 00:22:21
package com.visualbuilder;
import org.apache.struts.action.ActionForm;
(3) ActionClass
Note:- Now all the action classes must imherit the org.apache.struts.action.DispatchAction Class and not the
org.apache.struts.action.Action Class.
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;
42/121
01/14/11 00:22:21
ActionMessages message = new ActionMessages();
message.add(unspecified,new ActionMessage(error.view));
saveMessages(request, message);
return mapping.getInputForward();
}
public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception{
ActionMessages message = new ActionMessages();
message.add(unspecified,new ActionMessage(error.add));
saveMessages(request, message);
return mapping.getInputForward();
}
public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
ActionMessages message = new ActionMessages();
message.add(unspecified,new ActionMessage(error.delete));
saveMessages(request, message);
return mapping.getInputForward();
}
<logic:messagesPresent message=true>
<html:messages message=true id=msg>
<p><strong><bean:write name=msg /></strong></p>
</html:messages>
</logic:messagesPresent>
<html:form action=/dispatchActionExample.do?method=add method=post>
<html:submit>Submit for add</html:submit>
</html:form>
<html:form action=/dispatchActionExample.do?method=view method=post>
<html:submit>Submit for view</html:submit>
</html:form>
<html:form action=/dispatchActionExample.do?method=delete method=post>
<html:submit>Submit for delete</html:submit>
</html:form>
<html:form action=/dispatchActionExample.do method=post>
<html:submit>Submit for unspecified</html:submit>
43/121
01/14/11 00:22:21
</html:form>
</html:html>
Output:-
The following buttons will be displayed and on clicking the buttons the text delete called changes
44/121
01/14/11 00:22:21
Introduction to DynaActionForm
In struts, every form control need to have one ActionForm class property and getter/setter method for it. DynaActionForm
will replace the ActionForm with the simple xml mappings so that the java form class can be eliminated and thus helps in
developing the application more quickly. The advantages of using the DynaActionForm are as follows:-
1. No ActionForm is required.
2. Replace the property mapping with the simple xml file so that if any property is to add and remove then there is
no need to compile the java class again.
The mapping is to be done in the struts-config.xml file in the <form-bean> tag for all the form properties.
• java.math.BigDecimal
• java.math.BigInteger
• boolean and java.lang.Boolean
• byte and java.lang.Byte
• char and java.lang.Character
• java.lang.Class
• double and java.lang.Double
• float and java.lang.Float
• int and java.lang.Integer
• long and java.lang.Long
• short and java.lang.Short
• java.lang.String
• java.sql.Date
• java.sql.Time
• java.sql.Timestamp
45/121
01/14/11 00:22:21
<form-property name=email type=java.lang.String />
</form-bean>
</form-beans>
<!-- ========================================= Global Exception Definitions -->
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action path=/dynaActionExample
type=com.visualbuilder.DynaActionFormExample
name=inputForm
input=/index.jsp />
</action-mappings>
<!-- ======================================== Message Resources Definitions -->
<message-resources parameter=MessageResources />
</struts-config>
46/121
01/14/11 00:22:21
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.Action;
import org.apache.struts.action.DynaActionForm;
47/121
01/14/11 00:22:21
<html:html>
<logic:messagesPresent>
<html:messages id=msg>
<p><strong><font color=red><bean:write name=msg /></font></strong></p>
</html:messages>
</logic:messagesPresent>
<logic:messagesPresent message=true>
<html:messages message=true id=msg>
<p><strong><bean:write name=msg /></strong></p>
</html:messages>
</logic:messagesPresent>
<html:form action=/dynaActionExample.do method=post>
<table>
<tr><td>Enter the name :- </td><td><html:text property=name/> </td></tr>
<tr><td>Enter the Email:- </td><td><html:text property=email/></td></tr>
</table>
<html:submit>Submit</html:submit>
</html:form>
</html:html>
Output:-
48/121
01/14/11 00:22:21
The problem of duplicate form submission arises when a user clicks the Submit button more than once before the response
is sent back or when a client accesses a view by returning to a previously book marked page. The struts provide the
saveToken() and isTokenValid() to check whether the request is already submitted or not.
The method isValidToken() return true if there is a transaction token stored in the user's current session, and
the value submitted as a request parameter with this action matches it. Returns false under any of the
following circumstances:
Note:- If the Action class is changed as per the following code then it will validate against the duplicate form submission.
{
ActionMessages errors = new ActionMessages();
if (!isTokenValid(request)) {
errors.add(error.duplicaterequest, new ActionMessage(error.duplicaterequest));
}
resetToken(request);
if (!errors.isEmpty()) {
saveErrors(request, errors);
saveToken(request);
return (mapping.getInputForward());
}
return mapping.findForward(success);
}
Output
49/121
01/14/11 00:22:21
50/121
01/14/11 00:22:21
Introduction to Validation framework
We have seen the validate() method in ActionForm is used to validate the form properties, which are entered by the user
on the JSP pages. But each and every validation has to be implemented using the java code .In case the application has
similar kind of the validations for all the forms then the redundancy is increased. Also updating validation routines are
very cumbersome. The Validator framework was developed by David Winterfeldt as third-party add-on to Struts. The
advantages of the Validation Framework:-
1. It is XML based framework so it is very easy to modify the validation routines in the xml files as compared to the
Java files.
2. All the validations are at the same place so the reusability of the validations are very easy.
3. You can implement the validations in the Client Side as well as Server side with a little coding effort.
4. The validation framework is browser independent and needs no extra effort for the different browser in coding.
• Validations.xml :- This is the basic class consist of all the validation rules applied for a form bean.
• Validator-rules.xml:- This is the file which contains all the validation rules which can be used to validate the
form bean data. A default file is also provided by the Struts framework which is in /org/apache/struts/validator/
path and contains the commonly used rules,
• Plugin mapping in Struts-Config.xml:- The mapping of the plugin is to be there in the struts-config file so that
Struts controller class will configure the plugin so that it can be used in the application.
<form-validation>
<formset>
<form name=inputForm>
<field property=name depends=required>
<arg key=inputForm.name.required />
</field>
<field property=phone depends=required,mask>
<arg key=inputForm.phone.required position=0 />
<arg key=inputForm.phone.format position=1 />
<var>
<var-name>mask</var-name>
<var-value>^[0-9]*$</var-value>
51/121
01/14/11 00:22:21
</var>
</field>
<field property=email depends=required,email>
<arg key=inputForm.email.required position=0 />
<arg key=inputForm.email.format position=1 />
</field>
</form>
</formset>
</form-validation>
</struts-config>
52/121
01/14/11 00:22:21
package com.visualbuilder;
import org.apache.struts.validator.ValidatorForm;
String name;
String email;
String phone;
package com.visualbuilder;
53/121
01/14/11 00:22:21
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
54/121
01/14/11 00:22:21
<tr><td> Enter the Email</td>
<td><html:text property=email /></td></tr>
</table><html:submit>Submit </html:submit>
</html:form>
</html:html>
55/121
01/14/11 00:22:21
Client Side Validation
The validation framework also gives the flexibility to use it on Client Side. The framework automatically generates the
browser specific JavaScript and validate the data only at the client side. Although it has some disadvantages as the client
side validations can be turn off by browser settings and also it is visible to the client. It also has some advantages like it
reduces the network congestion as the form is not submitted with the wrong data again and again and only the validated
data is submitted. It is also advisable if you are using the client side validation scripts then also use the validation at the
server side so that two way check will maintain the data integrity fully.
The following code if placed in the jsp file will generate the java script at the client side for the specified form based on
the validations.xml file.
<html:javascript formName=inputForm/>
To call the validation routines call the onSubmit=validateXXX(this) whereas XXX stands for the form name. In our case it
is inputForm. So the code is as follows :-
56/121
01/14/11 00:22:21
The table will describe the validator rules available with the validator-rules.xml file provided by the Struts Community.
Rule Description
byte Checks value contained by field can be converted to java byte type
Checks value contained by field can be converted to java byte type using the number
byteLocale
formatting convention for the current locale.
Checks for the valid card number supplied by major companies like VISA,
creditCard
MASTERCARD etc.
date Checks value contained by field can be converted to java.util.Date.
double Checks value contained by field can be converted to double primitive type.
doubleRange Checks value contained by field can be fitted into the primitive double range or not.
email Checks value contained by field can be properly formatted email address or not.
float Checks value contained by field can be converted to float primitive type.
Checks value contained by field can be converted to java float type using the number
floatLocale
formatting convention for the current locale.
floatRange Checks value contained by field can be fitted into the primitive float range or not.
integer Checks value contained by field can be converted to int primitive type.
Checks value contained by field can be converted to java int type using the number
integerLocale
formatting convention for the current locale.
intRange Checks value contained by field can be fitted into the primitive int range or not.
long Checks value contained by field can be converted to long primitive type.
Checks value contained by field can be converted to java long type using the number
longLocale
formatting convention for the current locale.
longRange Checks value contained by field can be fitted into the primitive long range or not.
mask Validate the value with the given Regular Expression.
Validate the maximum length should not be exceeded of the value with the value given in
maxLength
the property.
Validate the minimum length should not be exceeded of the value with the value given in
minLength
the property.
required Checks whether the value contain by the field is other than the whitespace.
short Checks value contained by field can be converted to java short type
Checks value contained by field can be converted to java short type using the number
shortLocale
formatting convention for the current locale.
url Checks the given value is properly formatted URL or not.
validwhen Determine the field is validated or not based on the specified test condition.
57/121
01/14/11 00:22:21
The following is given the standard validator-rules.xml file. In the next section you will learn how to create your own
validator rules. Till the time we are using the same validator-rules.xml which is the standard file comes with standard
struts framework.
<!--
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You
under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an AS
IS BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<!DOCTYPE form-validation PUBLIC -//Apache Software Foundation//DTD Commons Validator Rules Configuration
1.3.0//EN http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd>
<!--
$Id: validator-rules.xml 481833 2006-12-03 17:32:52Z niallp $
This file contains the default Struts Validator pluggable validator definitions. It is contained in struts-core.jar, and should
be referenced in the struts-config.xml under the plug-in element for the ValidatorPlugIn.
<plug-in className=org.apache.struts.validator.ValidatorPlugIn>
<set-property property=pathnames value=/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml/>
</plug-in>
These are the default error messages associated with each validator defined in this file. They should be added to your
projects ApplicationResources.properties file or you can associate new ones by modifying the pluggable validators msg
attributes in this file.
errors.required={0} is required.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} characters.
errors.invalid={0} is invalid.
58/121
01/14/11 00:22:21
Note: Starting in Struts 1.2.0 the default javascript definitions have been consolidated to commons-validator. The default
can be overridden
by supplying a <javascript> element with a CDATA section, just as in struts 1.1.
-->
<form-validation>
<global>
<validator name=required
classname=org.apache.struts.validator.FieldChecks
method=validateRequired
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
msg=errors.required/>
<validator name=requiredif
classname=org.apache.struts.validator.FieldChecks
method=validateRequiredIf
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
msg=errors.required/>
<validator name=validwhen
msg=errors.required
classname=org.apache.struts.validator.validwhen.ValidWhen
method=validateValidWhen
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest/>
<validator name=minlength
classname=org.apache.struts.validator.FieldChecks
59/121
01/14/11 00:22:21
method=validateMinLength
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.minlength
jsFunction=org.apache.commons.validator.javascript.validateMinLength/>
<validator name=maxlength
classname=org.apache.struts.validator.FieldChecks
method=validateMaxLength
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.maxlength
jsFunction=org.apache.commons.validator.javascript.validateMaxLength/>
<validator name=mask
classname=org.apache.struts.validator.FieldChecks
method=validateMask
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.invalid/>
<validator name=byte
classname=org.apache.struts.validator.FieldChecks
method=validateByte
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.byte
jsFunctionName=ByteValidations/>
<validator name=short
classname=org.apache.struts.validator.FieldChecks
60/121
01/14/11 00:22:21
method=validateShort
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.short
jsFunctionName=ShortValidations/>
<validator name=integer
classname=org.apache.struts.validator.FieldChecks
method=validateInteger
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.integer
jsFunctionName=IntegerValidations/>
<validator name=long
classname=org.apache.struts.validator.FieldChecks
method=validateLong
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.long/>
<validator name=float
classname=org.apache.struts.validator.FieldChecks
method=validateFloat
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.float
jsFunctionName=FloatValidations/>
61/121
01/14/11 00:22:21
<validator name=double
classname=org.apache.struts.validator.FieldChecks
method=validateDouble
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.double/>
<validator name=byteLocale
classname=org.apache.struts.validator.FieldChecks
method=validateByteLocale
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.byte/>
<validator name=shortLocale
classname=org.apache.struts.validator.FieldChecks
method=validateShortLocale
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.short/>
<validator name=integerLocale
classname=org.apache.struts.validator.FieldChecks
method=validateIntegerLocale
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.integer/>
<validator name=longLocale
classname=org.apache.struts.validator.FieldChecks
method=validateLongLocale
62/121
01/14/11 00:22:21
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.long/>
<validator name=floatLocale
classname=org.apache.struts.validator.FieldChecks
method=validateFloatLocale
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.float/>
<validator name=doubleLocale
classname=org.apache.struts.validator.FieldChecks
method=validateDoubleLocale
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.double/>
<validator name=date
classname=org.apache.struts.validator.FieldChecks
method=validateDate
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.date
jsFunctionName=DateValidations/>
<validator name=intRange
classname=org.apache.struts.validator.FieldChecks
method=validateIntRange
63/121
01/14/11 00:22:21
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=integer
msg=errors.range/>
<validator name=longRange
classname=org.apache.struts.validator.FieldChecks
method=validateLongRange
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=long
msg=errors.range/>
<validator name=floatRange
classname=org.apache.struts.validator.FieldChecks
method=validateFloatRange
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=float
msg=errors.range/>
<validator name=doubleRange
classname=org.apache.struts.validator.FieldChecks
method=validateDoubleRange
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=double
msg=errors.range/>
<validator name=creditCard
classname=org.apache.struts.validator.FieldChecks
64/121
01/14/11 00:22:21
method=validateCreditCard
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.creditcard/>
<validator name=email
classname=org.apache.struts.validator.FieldChecks
method=validateEmail
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.email/>
<validator name=url
classname=org.apache.struts.validator.FieldChecks
method=validateUrl
methodParams=java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.url/>
<!--
This simply allows struts to include the validateUtilities into a page, it should not be used as a validation rule.
-->
<validator name=includeJavaScriptUtilities
65/121
01/14/11 00:22:21
Using validation framework in our application not only provide the basic routines for the validations but also gives the
user flexibility to create their own specific validator rules for the application. This is the powerful extensible feature as
this saves a lot more development and validation time during the application development. Below is given the complete
set of changes which should be performed while creating the custom validator rules for the application.
1. Create a class and add the static method for the validation.
2. Add the entry in the validator-rules.xml file.
3. Associate the rule with the form field.
4. Add the property in the MessageResources.properties for the error message.
Example
Note:- The example is merged with the Extending the Validation Rules with the inherited SubForm classes. You can see
the marks field which can only take values from 1 to 100. The below is the validation class for the example.
package com.visualbuilder.validator;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.validator.Resources;
/**
* This class is a custom validator which when apply to the framework checks The
* field should contain only alphabets
*
*/
public class CustomValidator implements Serializable {
public static boolean checkForRange(Object bean, ValidatorAction va, Field field, ActionMessages errors, Validator
validator,
HttpServletRequest request) {
boolean result = false;
String value = evaluateBean(bean, field);
try {
if (Integer.parseInt(value) > 0 && Integer.parseInt(value) < 100) {
result = true;
}
} catch (Exception e) {
66/121
01/14/11 00:22:21
}
if (!result) {
errors.add(field.getKey(), Resources.getActionMessage(validator, request, va, field));
}
return result;
}
67/121
01/14/11 00:22:21
Example Continued....
InputForm.java
package com.visualbuilder;
import org.apache.struts.validator.ValidatorForm;
String name;
String email;
String phone;
68/121
01/14/11 00:22:21
RegistrationForm.java
package com.visualbuilder;
ValidateAction.java
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
69/121
01/14/11 00:22:21
import org.apache.struts.action.ActionMapping;
RegisterAction.java
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
return mapping.getInputForward();
}
(6) Output
70/121
01/14/11 00:22:21
Internationalization in struts application
Few years back, the sites are only developed using a single language and the developer only create the sites to their
specific languages. As the globalization occurs, many frameworks are developed to support the multiple languages at a
time. This can be achieved by having the multi language text in key/value pair. And at runtime the text is read from the
key as per the language required. This multilingual support is known as Internationalization. So Internationalization is
defined as the process of designing an application so that it can be adapted to various languages and regions without
engineering changes.
• Locale - The fundamental Java class that supports internationalization is Locale . Each Locale represents a
particular choice of country and language, and also a set of formatting assumptions for things like numbers and
dates.
• ResourceBundle - The java.util.ResourceBundle class provides the fundamental tools for supporting messages in
multiple languages.
• PropertyResourceBundle - One of the standard implementations of Resource Bundle allows you to define
resources using the same name=value syntax used to initialize properties files. This is very convenient for
preparing resource bundles with messages that are used in a web application, because these messages are
generally text oriented.
• MessageFormat - The java.text.MessageFormat class allows you to replace portions of a message string with
arguments specified at run time. This is useful in cases where you are creating a sentence, but the words would
appear in a different order in different languages. The placeholder string {0} in the message is replaced by the
first runtime argument, {1} is replaced by the second argument, and so on.
• MessageResources - The framework class org.apache.struts.util.MessageResources lets you treat a set of
resource bundles like a database, and allows you to request a particular message string for a particular Locale
instead of for the default Locale the server itself is running in.
Note :- The example only displays the text coming from the different properties files. The properties file
MessageResource.properties is created with different locale suffix example fr is for France, de for Germany etc.. So the
example is only having the MessagesResources.properties and not the whole program. you can download the complete
source from the file. You can change the locale in the IE by tools>internet options>General---Languages and check the
program.
(1)MessageResources.properties
This is the default properties file. If the locale specific file is not present then struts calls the default properties file.
(2) MessageResources_en.properties
71/121
01/14/11 00:22:21
(3) MessageResources_fr.properties
(4) MessageResources_de.properties
72/121
01/14/11 00:22:21
Struts 1.3 provides a small, but effective exception-handling framework for the applications. There are two approaches
available for the exception handling in struts.
1. Declarative:- In this approach the exceptions are defined in the struts-config file and in case of the exception
occurs the control is automatically passed to the appropriate error page. The <exception> tag is used to define the
exception in the struts-config.xml file. The following are the attributes of the <exception> tag.
1. Key:- The key defines the key present in MessageResources.properties file to describe the exception
occurred.
2. Type:- The class of the exception occurred.
3. Path:- The page where the control is to be followed in case exception occurred.
4. Handler:- The exception handler which will be called before passing the control to the file specified in
path attribute
There are following two sections in struts-config.xml where you can define the exceptions.
♦ With Any Action mapping:- In this approach the action class is identified which may throw the exception
like password failure, resource access etc. For example:-
<action path=/exception
type=com.visualbuilder.ExampleAction
parameter=method
input=/index.jsp >
<exception key=error.system type=java.lang.RuntimeException path=/index.jsp />
</action>
♦ Defining the Exceptions Globally for the struts-config.xml :- If the application control is to pass on a
single page for all similar type of exception then the exception can be defined globally. So if in any
circumstance the exception occurs the control is passed globally to the exception and control is passed to
the error page. For Example:-
<global-exceptions>
<exception key=error.system type=java.lang.RuntimeException path=/index.jsp />
</global-exceptions>
2. Programmatic: - In this approach the exceptions are caught using normal java language try/catch block and
instead of showing the exception some meaningful messages are displayed. In this approach the flow of control is
also maintained by the programs. The main drawback of the approach is the developer has to write the code for
the flow of the application.
73/121
01/14/11 00:22:21
The struts not only introduced the exception handling mechanism and pass the flow to the appropriate page automatically,
it also gives the flexibility to the programmers to create their own Exception Handlers. The struts provides
org.apache.struts.action.ExceptionHandler class for creating the custom exception handlers. All the custom Exception
Handlers should extend the ExceptionHandler class and override the execute() method.
The below example will demonstrate custom ExceptionHandler for the user program.
Note:- The below example will transfer the control to the index.jsp after calling the exception handler. In the
struts-config.xml we are adding the global exception for RuntimeException. You can add any exception like the previous
example to some actions only. The code for adding it as follows :-
package com.visualbuilder.handler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.config.ExceptionConfig;
74/121
01/14/11 00:22:21
try {
// TODO CustomeCode
System.out.println(Exception Handler for the specific error);
}catch (Exception e) {
}
return (super.execute(exception, config, mapping, formInstance, request, response));
}
}
</form-beans>
<!-- ========================================= Global Exception Definitions -->
<global-exceptions>
</global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action path=/exception
type=com.visualbuilder.ExampleAction
input=/index.jsp />
</action-mappings>
<!-- ======================================== Message Resources Definitions -->
<message-resources parameter=MessageResources />
</struts-config>
75/121
01/14/11 00:22:21
The Action class is same as we have learned just with a small change. We are throwing an error from the Action Class. so
the code for the execute method is as follows:-
Note :- The below jsp will only call the Exception.do and then exception handler will pass the control again to this page.
76/121
01/14/11 00:22:21
(5) Output:-
The program will print Exception Handler for the specific error in the console window which shows that the
CustomExceptionHandler is called before redirecting to the specific page.
77/121
01/14/11 00:22:21
The struts provide org.apache.struts.action.PlugIn interface. All the custom Plugin should implement the PlugIn interface
and override the init() and destroy() methods.
package com.visualbuilder.plugin;
import javax.servlet.ServletException;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
78/121
01/14/11 00:22:21
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action path=/plugin
type=com.visualbuilder.TestPluginAction
input=/index.jsp >
<forward name=SUCCESS path=/index.jsp/>
</action>
</action-mappings>
<!-- ======================================== Message Resources Definitions -->
<message-resources parameter=MessageResources />
<!-- ======================================== Custom Plugin Definitions -->
<plug-in className=com.visualbuilder.plugin.CustomPlugin></plug-in>
</struts-config>
79/121
01/14/11 00:22:21
Example Continued....
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
(4) Output
Note:-The program will just print The plug in initialized when the server starts and Print Testing for the object when you
call the /plugin.do action.
80/121
01/14/11 00:22:21
Now a days the complex application are always bigger in size. So the number of action mappings will also increases.
Wildcards can be used to combine similar mappings into one more generic mapping and helps to reduce the size of the
config files.
Wildcard patterns can contain one or more of the following special tokens:
The action mapping attributes that will accept wildcard-matched strings are:
• attribute
• catalog
• command
• forward
• include
• input
• multipartClass
• name
• parameter
• prefix
• roles
• suffix
• type
The action forward attributes that will accept wildcard-matched strings are:
• catalog
• command
• path
(1) Struts-config.xml
Note:- In the action mapping the parameter is passed as {1}. The jsp which invoked the action replaces the parameter with
the name ofthe jsp in all places.
81/121
01/14/11 00:22:21
<?xml version=1.0 encoding=ISO-8859-1 ?>
</form-beans>
<!-- ========================================= Global Exception Definitions -->
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action path=/submit*
type=com.visualbuilder.Submit{1}Action
name={1}Form
scope=request
validate=false
input=/{1}.jsp/>
</action-mappings>
</struts-config>
82/121
01/14/11 00:22:21
SubmitRegisterAction.java file
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
SubmitInputAction.java file
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
83/121
01/14/11 00:22:21
import org.apache.struts.action.ActionMapping;
(3)Action Forms
InputForm.java file
package com.visualbuilder;
import org.apache.struts.validator.ValidatorForm;
String name;
String email;
String phone;
84/121
01/14/11 00:22:21
public String getName() {
return name;
}
RegisterForm.java file
package com.visualbuilder;
85/121
01/14/11 00:22:21
86/121
01/14/11 00:22:21
WildCard Character mapping for the Actions-3.
</html:html>
87/121
01/14/11 00:22:21
<html:form action=/submitRegister.do method=post>
<table>
<tr>
<td colspan=2>
<logic:messagesPresent>
<html:messages id=msg>
<p>
<strong><font color=red><bean:write name=msg /></font></strong>
</p>
</html:messages>
</logic:messagesPresent>
</td>
</tr>
<tr>
<td colspan=2>
<logic:messagesPresent message=true>
<html:messages message=true id=msg>
<p>
<strong><bean:write name=msg /></strong>
</p>
</html:messages>
</logic:messagesPresent>
</td>
</tr>
<tr><td>Enter the name</td>
<td><html:text property=name /></td></tr>
<tr><td> Enter the Phone</td>
<td> <html:text property=phone /></td></tr>
<tr><td> Enter the Email</td>
<td><html:text property=email /></td></tr>
<tr><td> Enter the Address </td>
<td><html:text property=address /></td></tr>
<tr><td> Enter the Marks </td>
<td><html:text property=marks /></td></tr>
</table><html:submit>Submit </html:submit>
</html:form>
</html:html>
(6) Output
Note:- When user submits the Register form and calls the submitRegister.do action then automatically the control calls
the submitRegisterAction class and prints Called SubmitRegisterAction file and same as for the submitInput.do calls the
submitInputAction class and prints Called SubmitInputAction file on the console.
88/121
01/14/11 00:22:21
Many applications gives the utility to upload the data from client applications to the server. Struts also gives the flexibility
to upload the files using the org.apache.struts.upload.FormFile class. The org.apache.struts.upload.FormFile class is a
special class in struts which represent the property type of file. The following example will demonstrate to upload any txt
file and place it in the upload folder by the name of temp.txt.
Example:-
</form-beans>
<!-- ========================================= Global Exception Definitions -->
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action
path=/submit
type=com.visualbuilder.InputAction
name=inputForm
scope=request
validate=false
input=/index.jsp/>
</action-mappings>
</struts-config>
package com.visualbuilder;
89/121
01/14/11 00:22:21
import org.apache.struts.upload.FormFile;
import org.apache.struts.validator.ValidatorForm;
90/121
01/14/11 00:22:21
package com.visualbuilder;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.Globals;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.upload.FormFile;
91/121
01/14/11 00:22:21
Generally, all the applications and systems are modularized so that the time of development and complexity can be
reduced. The struts also give the flexibility to have more than one independent modules in the application. The separate
struts-config files are introduced for each module. This helps developers to develop the complex applications more
effectively as different independent applications can be developed separately and then combined together to make a
complete system. The struts gives a special Action class, SwitchAction , which is used for the switching between the
modules. The below example will demonstrate the modules in the Struts Applications.
The following things needs to be changed to make more than one modules in the application.
• All the module specific config files should be kept on the module specific directories under WEB-INF folder.
• All the jsp files for the module should be kept under the module folder.
• All the module specific files should be passed in the ActionServlet in the Web.xml file.
There are three approaches for switching from one module to another.
Note:- The coming example will demonstrate the all three approaches for the application
92/121
01/14/11 00:22:21
Modules Example-1
Note:- In the below example we are creating the admin and register module. You can download the whole source from
download link. We only show the code which is written for the modules so that you can understand the exact logic to
switch the modules.
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/admin</param-name>
<param-value>/WEB-INF/admin/struts-admin.xml</param-value>
</init-param>
<init-param>
<param-name>config/register</param-name>
<param-value>/WEB-INF/register/struts-register.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
93/121
01/14/11 00:22:21
Modules Example-2
94/121
01/14/11 00:22:21
(8) Output:-
Note:- On running the default module index.jsp file the following output will be displayed on the screen.
95/121
01/14/11 00:22:21
Struts follow the Model-View-Controller pattern. ActionServlet provides the controller in the MVC design pattern for
web applications that is commonly known as Model 2. The standard version of ActionServlet is configured based on the
following servlet initialization parameters,
• config - Comma-separated list of context-relative path(s) to the XML resource(s) containing the configuration
information for the default module. (Multiple files support since Struts 1.1) [/WEB-INF/struts-config.xml].
• config/${module} - Comma-separated list of Context-relative path(s) to the XML resource(s) containing the
configuration information for the module that will use the specified prefix (/${module}). This can be repeated as
many times as required for multiple modules.
• configFactory - The Java class name of the ModuleConfigFactory used to create the implementation of the
ModuleConfig interface.
• convertNull - Force simulation of the Struts 1.0 behavior when populating forms. If set to true, the numeric Java
wrapper class types (like java.lang.Integer ) will default to null (rather than 0). (Since Struts 1.1) [false]
• rulesets - Comma-delimited list of fully qualified classnames of additional org.apache.commons.digester.RuleSet
instances that should be added to the Digester that will be processing struts-config.xml files. By default, only the
RuleSet for the standard configuration elements is loaded.
• validating - Should we use a validating XML parser to process the configuration file (strongly recommended)?
[true]
• chainConfig - Comma-separated list of either context-relative or classloader path(s) to load commons-chain
catalog definitions from. If none specified, the default Struts catalog that is provided with Struts will be used.
The main power of struts is that you can customize the controller behaviour if needed by your application. The below
example will demonstrate to override the default functionality of the controller and do some application specific
processing before and after the request has been processed.
</form-beans>
<!-- ========================================= Global Exception Definitions -->
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action
path=/submit
type=com.visualbuilder.SubmitAction
name=inputForm
scope=request
validate=false
96/121
01/14/11 00:22:21
input=/index.jsp/>
</action-mappings>
<!-- ======================================== Message Resources Definitions -->
<message-resources parameter=MessageResources />
97/121
01/14/11 00:22:21
The mapping for the ActionServlet class is written in the web.xml file so we have to change it for mapping our
CustomActionServlet class.
(3)CustomActionServlet.java file
This is the file which is the replaces the Struts Controller class. We extends the Struts ActionServlet to get the default
behaviour and override the process method.
package com.visualbuilder;
import java.io.IOException;
98/121
01/14/11 00:22:21
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionServlet;
(4)InputForm.java file
package com.visualbuilder;
import org.apache.struts.validator.ValidatorForm;
String name;
String email;
String phone;
99/121
01/14/11 00:22:21
public void setEmail(String email) {
this.email = email;
}
100/121
01/14/11 00:22:21
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
(6)Index.jsp file
101/121
01/14/11 00:22:21
<td colspan=2>
<logic:messagesPresent message=true>
<html:messages message=true id=msg>
<p>
<strong><bean:write name=msg /></strong>
</p>
</html:messages>
</logic:messagesPresent>
</td>
</tr>
<tr><td>Enter the name</td>
<td><html:text property=name /></td></tr>
<tr><td> Enter the Phone</td>
<td> <html:text property=phone /></td></tr>
<tr><td> Enter the Email</td>
<td><html:text property=email /></td></tr>
</table><html:submit>Submit </html:submit>
</html:form>
</html:html>
(7)Output
Note:- Whenever the request is submitted to the application you see two line Before Handling Request and After Handling
Request printing on the console and the line Called Submit file is printed in between. This shows that for every request the
code of CustomActionServlet gets called.
102/121
01/14/11 00:22:21
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
(6)Index.jsp file
103/121
01/14/11 00:22:21
<td colspan=2>
<logic:messagesPresent message=true>
<html:messages message=true id=msg>
<p>
<strong><bean:write name=msg /></strong>
</p>
</html:messages>
</logic:messagesPresent>
</td>
</tr>
<tr><td>Enter the name</td>
<td><html:text property=name /></td></tr>
<tr><td> Enter the Phone</td>
<td> <html:text property=phone /></td></tr>
<tr><td> Enter the Email</td>
<td><html:text property=email /></td></tr>
</table><html:submit>Submit </html:submit>
</html:form>
</html:html>
(7)Output
Note:- Whenever the request is submitted to the application you see two line Before Handling Request and After Handling
Request printing on the console and the line Called Submit file is printed in between. This shows that for every request the
code of CustomActionServlet gets called.
104/121
01/14/11 00:22:21
Customizing RequestProcessor Class for the application-1.
The previous example has shown you to customize the controller before and after any request processed. But Struts
provide a class named RequestProcessor which actually done all the processing for a particular request. In Struts 1.0 the
whole things are done by the ActionServlet class. But with the next release the request processing code shifted to
RequestProcessor class. RequestProcessor contains the processing logic that the ActionServlet performs as it receives
each servlet request from the container. You can customize the request processing behavior by subclassing this class and
overriding the method(s) whose behavior you are interested in changing. the following methods are available in the
RequestProcessor Class.
Note:- The below example will demonstrate the overriding of methods in the RequestProcessor class. The example will
override processPreprocess() method of the RequestProcessor Class. >
(1)Struts-config.xml file
Note - RequestProcessor mapping is given by the <controller> tag in the struts-config.xml file.
</form-beans>
<!-- ========================================= Global Exception Definitions -->
105/121
01/14/11 00:22:21
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action
path=/submit
type=com.visualbuilder.SubmitAction
name=inputForm
scope=request
validate=false
input=/index.jsp/>
</action-mappings>
</struts-config>
106/121
01/14/11 00:22:21
package com.visualbuilder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.RequestProcessor;
Note:- Only the above specified files are addition to the previous example i.e.Customizing the ActionServlet Class for the
application.
(3) Output
The text Called the preprocess method before processing the request gets printed each time the request is processed by the
Struts. This shows that it is calling the CustomRequestProcessor and not the RequestProcessor class.
107/121
01/14/11 00:22:21
Introduction :- A popular technique for organizing the execution of complex processing flows is the Chain of
Responsibility pattern. In this pattern the different “commands” are combined into a single chain with a series of
processing elements and the context parameter is passed along with all the parameter. All the commands contain a single
execute method. A Boolean variable determines whether the command executes successfully or not. This pattern promotes
the idea of loose coupling, a common programming practice.
From the version 1.3, the struts replaces the RequestProcessor with ComposableRequestProcessor class which follows the
Chain of Responsibility pattern (CoR) design pattern. It is configured via the following context initialization parameters:
Each step of the processing is represented as a separate Command in the Chain. User can easily customize by changing,
removing and replacing the chain commands. The Command classes are following packages:-
1. org.apache.struts.chain.commands.
2. org.apache.struts.chain.commands.servlet packages.
The following table will listed out all the command objects of CoR.
Command Description
Select a locale for this request, if one hasn't already been selected, and place it in the
SelectLocale
request.
SetOriginalURI Store the URI of the original request in the request.
RequestNoCache If appropriate, set the following response headers: Pragma, Cache-Control, and Expires.
Removes any ActionMessages object stored in the session under Globals.MESSAGE_KEY
RemoveCachedMessages and Globals.ERROR_KEY if the messages' isAccessed method returns true. This allows
messages to be stored in the session, displayed one time, and be released.
SetContentType Set the default content type (with optional character encoding) for all responses if requested.
SelectAction Determine the ActionMapping associated with this path.
If the mapping has a role associated with it, ensure the requesting client has the specified
AuthorizeAction
role. If the client does not, raise an error and stop processing of the request.
Instantiate (if necessary) the ActionForm associated with this mapping (if any) and place it
CreateActionForm
into the appropriate scope.
PopulateActionForm Populate the ActionForm associated with this request, if any.
ValidateActionForm Perform validation (if requested) on the ActionForm associated with this request (if any).
SelectInput If validation failed, select the appropriate ForwardConfig for return to the input page.
ExecuteCommand Lookup and execute a chain command if the current ActionConfig is so-configured.
SelectForward If this mapping represents a forward, forward to the path specified by the mapping.
SelectInclude Select the include uri (if any) for the current action mapping.
108/121
01/14/11 00:22:21
PerformInclude If selected, include the result of invoking the path in this request.
CreateAction Instantiate an instance of the class specified by the current ActionMapping (if necessary).
ExecuteAction This is the point at which your Action's execute method will be called.
ExecuteForwardCommand Lookup and execute a chain command if the current ForwardConfig is so-configured.
Finally, the process method of the RequestProcessor takes the ActionForward returned by
PerformForward your Action class, and uses it to select the next resource (if any). Most often the
ActionForward leads to the presentation page that renders the response.
<catalog name=struts>
<chain name=servlet-standard>
109/121
01/14/11 00:22:21
</chain>
<!--
This chain attempts to emulate (most of) the standard request processing in the standard
org.apache.struts.action.RequestProcessor class, by performing the corresponding tasks in individual Commands
that are composable. The following list defines a cross reference between the processXxx methods and the Commands
that perform the corresponding functionality:
processLocale SelectLocale
processContent SetContentType
processNoCache RequestNoCache
processPreprocess LookupCommand with optional=true. Multiple occurrences of this can easily be added, to support
additional processing hooks at any point in the chain without modifying the standard definition.
processCachedMessages RemoveCachedMessages
processRoles AuthorizeAction
processActionForm CreateActionForm
processPopulate PopulateActionForm
processForward SelectForward
processActionCreate CreateAction
processActionPerform ExecuteAction
-->
<!-- Look up optional preprocess command -->
110/121
01/14/11 00:22:21
<!-- Set (if needed) the URI of the original request -->
<command className=org.apache.struts.chain.commands.servlet.SetOriginalURI/>
<!-- Set (if needed) the HTTP response content type -->
<command className=org.apache.struts.chain.commands.servlet.SetContentType/>
<!-- Create (if needed) the ActionForm for this request -->
<command className=org.apache.struts.chain.commands.CreateActionForm/>
<!-- Select the appropriate ForwardConfig for return to input page -->
<command className=org.apache.struts.chain.commands.servlet.SelectInput/>
<!-- Lookup and execute a chain command if the current ActionConfig is so-configured. -->
<command className=org.apache.struts.chain.commands.ExecuteCommand/>
<!-- Select the appropriate ForwardConfig for action mappings that only have an ActionForward -->
<command className=org.apache.struts.chain.commands.servlet.SelectForward/>
<!-- Select the include uri (if any) for the current action mapping -->
<command className=org.apache.struts.chain.commands.SelectInclude/>
<!-- Create (if needed) the Action for this request -->
<command className=org.apache.struts.chain.commands.servlet.CreateAction/>
111/121
01/14/11 00:22:21
</chain>
<!-- Lookup and execute a chain command if the current ForwardConfig is so-configured. -->
<command className=org.apache.struts.chain.commands.ExecuteForwardCommand/>
</chain>
<chain name=servlet-exception>
<!--
This chain is designed to be invoked (by o.a.s.c.ExceptionCatcher) if an unhandled exception is thrown by any subsequent
command in a processing chain (including the one that invokes a Struts action). The standard definition of this chain
supports the exception mapping of Struts 1.1, but can be replaced in order to handle exceptions differently.
-->
</chain>
</catalog>
112/121
01/14/11 00:22:21
The Struts new CoR(Chain of Responsibility) structure gives us more flexibility to add our commands in between the
request processing and also with less effort. All the user needs is to extend
org.apache.struts.chain.commands.ActionCommandBase class and override the execute() method in it.
The below example will demonstrate how do we insert our own command objects in the existing Struts CoR without
changing the actual flow and the ComposeableRequestProcessor will call the file implicitly. For any type of addition and
deletion of the commands only the chain-config.xml file is changed and the Struts automatically take care of the flow.
(1) Struts-config.xml
</form-beans>
<!-- ========================================= Global Exception Definitions -->
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action
path=/submit
type=com.visualbuilder.SubmitAction
name=inputForm
scope=request
validate=false
input=/index.jsp/>
</action-mappings>
</struts-config>
113/121
01/14/11 00:22:21
Note:- The following file is created for the command object. If it returns true it means some exception occurred so it wont
call the next Command in the chain and returns to the input jsp file.
package com.visualbuilder.command;
import org.apache.struts.chain.commands.ActionCommandBase;
import org.apache.struts.chain.contexts.ActionContext;
@Override
public boolean execute(ActionContext ctx) throws Exception {
boolean result=true;
System.out.println(Called the logic for the Custom Command);
return false;
}
Note :- The following command will be added in the chain-config.xml file anywhere in the process-action chain.
114/121
01/14/11 00:22:21
Security in Struts
The following is the Example to implement the Container Specific Security in Tomcat.
115/121
01/14/11 00:22:21
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>securityapp</realm-name>
</login-config>
<security-role>
<description>Testing the Application Security</description>
<role-name>admin</role-name>
</security-role>
</web-app>
Output:-
The following screen appears when you try to run the application. It will ask for username and password and once you
enter visualbuilder as username and test as password then only it will display the pages of the application.
116/121
01/14/11 00:22:21
117/121
01/14/11 00:22:21
<global-exceptions></global-exceptions>
<!-- =========================================== Global Forward Definitions -->
<global-forwards></global-forwards>
<!-- =========================================== Action Mapping Definitions -->
<action-mappings>
<action path=/submit
type=com.visualbuilder.SubmitAction
scope=request validate=false
name=inputForm input=/index.jsp
roles=admin/>
</action-mappings>
<!-- =========================================== Controller Mapping Definition -->
<controller contentType=text/html;charset=UTF-8 locale=true debug=1 nocache=true
processorClass=org.apache.struts.chain.ComposableRequestProcessor />
</struts-config>
118/121
01/14/11 00:22:21
Note:- The only change with in this file is to replace line number 1 by the line number 2.
119/121
01/14/11 00:22:21
Note:- If any security check application is to be created in the struts 1.3 or higher then
org.apache.struts.chain.commands.AbstractAuthorizeAction is to be extended but in case of previous versions the
RequestProceesor's method processRoles() is to be overridden to check the security setting of the user.
package com.visualbuilder.command;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.chain.commands.AbstractAuthorizeAction;
import org.apache.struts.chain.contexts.ActionContext;
import org.apache.struts.chain.contexts.ServletActionContext;
import org.apache.struts.config.ActionConfig;
import org.apache.struts.util.MessageResources;
import javax.servlet.http.HttpServletRequest;
120/121
01/14/11 00:22:21
Note:- Rest all the same as the previous composablerequestprocessor example for the application.
Output:-
Note:- If the role admin is entered only then the submit action gets called otherwise the following exception comes to the
screen.
121/121