You are on page 1of 72

1

POTHURAI

Struts

A frame work simplifies the development of the complex applications. The frame
work software’s are designed based on very good architecture.
Ex: - Struts, Spring MVC, web works are designed based on MVC architecture.
A frame work contains the code that is commonly required as part of almost every
project. A frame work provides a standard procedure for doing every task. This makes
the development of the application: easier than development of an app with without using
a frame work.

 package org.students;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class OurActionServlet extends HttpServlet
{
public void init( )throws ServletException
{
System.out.println("----reading xxx.xml----");
}
public void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
{
System.out.println("----OurActionServlet----"+request.getRequestURI( ));
}
}
D:\Pskr\Struts>javac -d . OurActionServlet.java

 <web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.students.OurActionServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>

Start weblogic server


----reading xxx.xml----
http://localhost:8000/str/one.do
----OurActionServlet----/str/one.do
http://localhost:8000/str/xxx/yyy.do
----OurActionServlet----/str/xxx/yyy.do

SUDHEER REDDY
2
POTHURAI

action(*.do)
/one.do

/xxx/yyy.do
web.xml
init( ) {
-----------
} Browser

org.students.OurActionServlet

xxx.xml
web container
The following steps will be carried out while starting the above web application: -
1) Web container reads web.xml.
2) As we have used load-on-startup, web container creates OurActionServlet obj.
3) Web container calls the init( ).
4) The init( ) method reads the information available in xxx.xml.
Note: - Web container executes OurActionServlet code when it receives the request sent
using the URL that ends with .do

We get the following things as part of Struts frame work: -


1) A set of tag libraries like struts-html, struts-logic, struts-bean, struts-tiles etc…
2) A servlet class with the name org.apache.struts.action.ActionServlet.
3) A set of classes like Action, ActionForm, ActonError, ActionErrors etc… these
classes are used as part of our code.
Procedure for setting up a struts based web applications: -
1) Create a Root directory for the web application
Ex: - d:\str
2) Copy struts-blank.war to d:\pskr
3) Using cd command move to the directory str & use the jar command to extract the
content of the war file
d:\str>jsr cf struts-blank.war .
4) Copy str directory & place this directory in weblogic
D:\bea\user_projects\domains\sunil\applications\ directory
In tomcat D:\Tomcat5.0\webapps\ directory
 <web-app>
<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>
<load-on-startup>2</load-on-startup>
</servlet>

SUDHEER REDDY
3
POTHURAI
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/tags/struts-bean</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-html</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-logic</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-nested</taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/tags/struts-tiles</taglib-uri>
<taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
</taglib>
</web-app>

The following steps will carry out when a struts base application will start: -
1) Web container reads web.xml
2) Web container creates a servlet object based on ActionServlet class
3) Web container calls the init( ) method on ActionServlet.
4) Struts code that is part of the init( ) method reads the information available in
struts-config.xml
Note: - Web container executes the code of the ActionServlet, when it receive a request
that ends with .do

action(*.do) /aone.do

web.xml /axxx.do
init( ) {
struts code
} Browser

org.apache.struts.action.ActionServlet

struts-config.xml web container

SUDHEER REDDY
4
POTHURAI
 In order to take care of various tasks (actions), various action classes must be
provided in our Struts based project.
An Action class is sub class of org.apache.struts.action.Action
To compile the Action classes: - 1) copy struts.jar, servlet-api.jar/weblogic.jar to the
working directory (d:\pskr\struts\). 2) Use the command shown below for setting the class
path
D:\pskr\struts>set CLASSPATH=.;struts.jar;servlet-api.jar; (or)
D:\pskr\struts>set CLASSPATH=.;struts.jar;weblogic.jar;

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionOne extends Action
{
public ActionOne( )
{
System.out.println("----ActionOne created----");
}
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response)
throws Exception
{
System.out.println("----ActionOne:execute----");
return null;
}
}
D:\Pskr\Struts>set CLASSPATH=.;struts.jar;servlet-api.jar;
D:\Pskr\Struts>javac ActionOne.java

Procedure for using the Action class in a Struts project: -


1) Copy the Action class in WEB-INF/classes directory.
2) Provide the information about the Action class in struts-config.xml
 <action-mappings>
<action path="/aone" type="ActionOne"/>
<action path="/atwo" type="ActionTwo">
<forward name="fone" path="/one.jsp"/> action-mapping
<forward name="ftwo" path="/two.jsp"/>
</action>
</action-mappings>
http://localhost:8000/str/aone.do
----ActionOne created----
----ActionOne:execute----

The following steps will be carried out in the container when it receives the request for
/aone.do: -
Step1: - Web container creates req, resp objects
2) Web container starts the execution of the struts code of Action Servlet by providing
req, resp objects.

SUDHEER REDDY
5
POTHURAI

ActionServlet obj
req /aone.do

resp
action(*.do)

execute(…. Web browser


)
ActionOne obj

web server
3) The Struts code gets the name of the Action class (ActionOne) mapped to the path
/aone.
4) If required ActionOne object will be created by struts code.
5) Struts code calls the execute method on ActionOne object (req, resp created in step1
will be provided to the execute( ) method).
6) As the execute( ) method returns null the struts code stops processing the request.

Struts code creates the ActionForward objects & places the information available
in the forward tag in this object. Struts code places the information available action tag
inside the ActionMapping object.

name=fone
path=/one.jsp

path=/atwo ActionForward
type=ActioTwo
name=ftwo
path=/two.jsp
ActionMapping obj

ActionForward
 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionTwo extends Action
{
public ActionTwo( )
{
System.out.println("---- ActionTwo created----");
}
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----ActionTwo:execute----");
System.out.println(mapping.getPath( ));

SUDHEER REDDY
6
POTHURAI
System.out.println(mapping.getType( ));
ActionForward af1,af2,af3;
af1=mapping.findForward("fone");
System.out.println("af1--->"+af1);
af2=mapping.findForward("ftwo");
System.out.println("af2--->"+af2);
af3=mapping.findForward("fthr");
System.out.println("af3--->"+af3);
return af1;
}
}
D:\Pskr\Struts>javac ActionTwo.java

 <% System.out.println("---one.jsp---");%>
op generated by one.jsp
http://localhost:8000/str/atwo.do
---- ActionTwo created----
----ActionTwo:execute----
/atwo
ActionTwo
af1--->ForwardConfig[name=fone,path=/one.jsp,redirect=false,contextRelative=false]
af2--->ForwardConfig[name=ftwo,path=/two.jsp,redirect=false,contextRelative=false]
af3--->null
---one.jsp---
op generated by one.jsp

ActionServlet obj
req /atwo.do

resp
action(*.do)

execute(…. Web browser


)
ActionTwo obj

one.jsp

Web server
The following steps will be carried out in the container when it receives the request for
/aone.do: -
Step1: - Web container creates req, resp objects
2) Web container starts the execution of the struts code of Action Servlet by providing
req, resp objects.
3) The Struts code gets the name of the Action class (ActionTwo) mapped to the path
/atwo.

SUDHEER REDDY
7
POTHURAI
4) If required ActioTwo object will be created by struts code.
5) Struts code calls the execute method on ActionTwo object (req, resp created in step1
will be provided to the execute( ) method).
6) As the execute( ) method returns af1 the struts code forward the request to one.jsp.
7) one.jsp generate to the output.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class GDAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
java.util.Vector v=new java.util.Vector( );
v.add("DIOne");
v.add("DITwo");
v.add("DIThree");
v.add("DIFour");
request.setAttribute("svdata",v);
System.out.println("Stored vector in req");
System.out.println("Returning genop fwd");
return mapping.findForward("genop");
}
}
D:\Pskr\Struts>javac GDAction.java

 <action-mappings>
<action path="/gda" type="GDAction">
<forward name="genop" path="/genrep.jsp"/>
</action>
</action-mappings>

 <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>


<% System.out.println("---genrep.jsp---"); %>
<c:forEach var="s" items="${requestScope.svdata}">
<c:out value="${s}"/> <br>
</c:forEach>

http://localhost:8000/gda/gda.do
Stored vector in req
Returning genop fwd
---genrep.jsp---
DIOne
DITwo
DIThree
DIFour

SUDHEER REDDY
8
POTHURAI
The following steps will be carried out in the container when it receives the request for
/gda.do: -

ActionServlet obj
req
svdat /gda.do
a
action(*.do)
resp
execute(…. Web browser
)
GDAction obj
String objects

genrep.jsp
Vector

Web Container
Step1: - Web container creates req, resp objects.
2) Web container starts the execution of the struts code available in Action Servlet.
3) If required struts code creates GDAction object.
4) Struts code calls the execute method on GDAction.
5) The code of GDAction stores a vector object that contains 4 string objects inside t he
request & returns a forward with the name genop.
6) Struts code forward the request to genrep.jsp.
7) genrep.jsp generates the output that contains the string objects available in the vector.

 SQL> select * from student;


SNO SNAME FNAME ADDR
---------- -------------------- -------------------- -----------------
1 sone fone aone
1 stwo ftwo atwo

 package org.students;
public class StudentBean
{
String studNo;
String studName;
String fatherName;
String addr;
public void setStudNo(String studNo)
{
System.out.println("----setStudNo---->"+studNo);
this.studNo=studNo;
}
public String getStudNo( )
{

SUDHEER REDDY
9
POTHURAI
System.out.println("----getStudNo---->"+this.studNo);
return this.studNo;
}
public void setStudName(String studName)
{
System.out.println("----setStudName---->"+studName);
this.studName=studName;
}
public String getStudName( )
{
System.out.println("----getStudName---->"+this.studName);
return this.studName;
}
public void setFatherName(String fatherName)
{
System.out.println("----setFatherName---->"+fatherName);
this.fatherName=fatherName;
}
public String getFatherName( )
{
System.out.println("----getFatherName---->"+this.fatherName);
return this.fatherName;
}
public void setAddr(String addr)
{
System.out.println("----setAddr---->"+addr);
this.addr=addr;
}
public String getAddr( )
{
System.out.println("----getAddr---->"+this.addr);
return this.addr;
}
}
D:\Pskr\Struts>javac –d . StudentBean.java

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
public class GSDAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection

SUDHEER REDDY
10
POTHURAI
("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
String vsql="select * from student";
java.util.Vector v=new java.util.Vector( );
Statement stmt=con.createStatement( );
ResultSet rs=stmt.executeQuery(vsql);
while(rs.next( ))
{
org.students.StudentBean sb=new org.students.StudentBean();
sb.setStudNo(rs.getString("sno"));
sb.setStudName(rs.getString("sname"));
sb.setFatherName(rs.getString("fname"));
sb.setAddr(rs.getString("addr"));
v.add(sb);
}
con.close( );
request.setAttribute("svsdata",v);
return mapping.findForward("gensrep");
}
}

 <action-mappings>
<action path="/gsda" type="GSDAction">
<forward name="gensrep" path="/gensrep.jsp"/>
</action>
</action-mappings>

 <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>


<% System.out.println("---gensrep.jsp---"); %>
<c:forEach var="s" items="${requestScope.svsdata}">
<c:out value="${s.studNo}"/> <br>
<c:out value="${s.studName}"/> <br>
<c:out value="${s.fatherName}"/> <br>
<c:out value="${s.addr}"/> <br>
---------------<br>
</c:forEach>
http://localhost:8000/gsda/gsda.do
----setStudNo---->1
----setStudName---->sone
----setFatherName---->fone
----setAddr---->aone
----setStudNo---->1
----setStudName---->stwo
----setFatherName---->ftwo
----setAddr---->atwo
---gensrep.jsp---
----getStudNo---->1
----getStudName---->sone

SUDHEER REDDY
11
POTHURAI
----getFatherName---->fone
----getAddr---->aone
----getStudNo---->1
----getStudName---->stwo
----getFatherName---->ftwo
----getAddr---->atwo
1
sone
fone
aone
---------------
1
stwo
ftwo
atwo
---------------
The following steps will be carried out in the container when it receives the request for
/gsda.do: -

ActionServlet obj
req
svsdat /gsda.do
a
op generated by
action(*.do) gensrep.jsp
resp
execute(…. Web browser
)
GSDAction obj
StudentBean

gensrep.jsp
Vector
Web Container
Step1: - Web container creates req, resp objects.
2) Web container starts the execution of the struts code by passing req, resp objects.
3) If required GSDAction object will be created by struts code.
4) Struts code calls the execute method on GSDAction.
5) The code of GSDAction performs the following steps.
a) Executes select statement for getting data from student table.
b) Creates s Vector object.
c) Loads the data in StudentBean object & place these objects inside the Vector.
d) Places the Vector inside the request object.
e) Returns a forward with the name gensrep.
6) Struts code forward the request to gensrep.jsp.
7) gensrep.jsp generates the output that contains the data available in StudentBean
objects.
i18n: - Struts support (simplifies) the development of i18n application.

SUDHEER REDDY
12
POTHURAI
D:\psr\J2EE>java HWebServer1 8000
http://localhost:8000/
Accept-Language: en_US
Internet Explorer  Tools  internet option  languages

 Click add button

 click ok button

 Re-start the browser

SUDHEER REDDY
13
POTHURAI
http://localhost:8000/
Accept-Language: te

Locale
Client
Accept-Language: en_US

US (english)

Accept-Language: te
Client

te (telugu)
As part of every request Accept-Language Header will be sent by the browser.
This Header provides Locale (language code, country code) setting of the browser tp the
server (web application).
As part of our Servlets/ JSP’s, the code shown below can be used for getting
the information about the Locale setting of the browser.

 <%
java.util.Locale loc;
loc=request.getLocale( );
out.println(loc);
%>
http://localhost:7001/i18n/loc.jsp
te

 Select the language French (Canada) [fr-ca] in the internet explorer.


http://localhost:7001/i18n/loc.jsp
fr_CA

 <html>
<head>
<title> Welcome </title>
</head>
<body> These Strings must be
<br> Welcome to Our web App different for various Locale’s
<br> line two pone
<br> line three of pone
</body>
</html>

Note: - The html tags are same for the entire Locale’s.

SUDHEER REDDY
14
POTHURAI
In a i18n application the Locale specific Strings should not be used directly as
shown above JSP.

Procedure for developing i18n application: -


Step 1: - We must provide the information about the Locale specific strings in the
properties files as shown below

 pone.title=Welcome
pone.lone=welcome to our web app
pone.ltwo=line two of pone ourres_en_US.properties
pone.lthr=line three of pone

 pone.title=Welcome in fr
pone.lone=welcome to our web app in fr
pone.ltwo=line two of pone in fr ourres_fr_CA.properties
pone.lthr=line three of pone in fr

Note: - We must use the name ourres.properties, to use this as default in our web
application.
The properties files must be placed under WEB-INF\classes directory.

Step 2: - Provide the information about the properties file in struts-config.xml as shown
below
<message-resources parameter="ourres"/>
Step 3: - We can use message tag of struts-bean tag library, for accessing the resources
available in the properties files.

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


<html>
<head>
<title> <bean:message key="pone.title"/> </title>
</head>
<body>
<bean:message key="pone.lone"/> <br>
<bean:message key="pone.ltwo"/> <br>
<bean:message key="pone.lthr"/> <br>
</body>
</html>
http://localhost:7001/i18n/pone.jsp
welcome to our web app in fr
line two of pone in fr
line three of pone in fr
 Select the language English (United States) [en-US] in the internet explorer.
http://localhost:7001/i18n/pone.jsp
welcome to our web app
line two of pone
line three of pone

SUDHEER REDDY
15
POTHURAI
 <%
Object o=application.getAttribute("attname");
out.println(o);
%>
http://localhost:7001/i18n/aobj.jsp
null
 <%
Object o=application.getAttribute("org.apache.struts.action.MESSAGE");
out.println(o);
%>
http://localhost:7001/i18n/mobj.jsp
org.apache.struts.util.PropertyMessageResources@14c7cd

org.apache.struts.action.MESSAGE Resources of
ourres.properties

ServletContext(application obj) PropertyMassageResources

During startup the struts code PropertyMassageResources objects, loads the


MassageResources available in properties files with the base home ourres. Struts code
stores PropertyMassageResources inside the application object with the attribute name
org.apache.struts.action.MESSAGE (this is called as default key).

 The PropertyMessageResources object will be stored in ServletContext with the


attribute name xxx, if we provide the information as shown below in struts-config.xml.
<message-resources key="xxx" parameter="ourres"/>

 <%
Object o=application.getAttribute("org.apache.struts.action.MESSAGE");
out.println(o);
%>
http://localhost:7001/i18n/mobj.jsp
null

 <%
Object o=application.getAttribute("xxx");
out.println(o);
%>
http://localhost:7001/i18n/xobj.jsp
org.apache.struts.util.PropertyMessageResources@1c1eceb

xxx Resources of
ourres.properties

ServletContext(application obj) PropertyMassageResources

SUDHEER REDDY
16
POTHURAI
http://localhost:7001/i18n/pone.jsp
Error 500--Internal Server Error
javax.servlet.jsp.JspException: Cannot find message resources under key
org.apache.struts.action.MESSAGE

if key is specified as xxx in the struts-config.xml file, then we must used the message tag
as shown below.

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


<html>
<head>
<title> <bean:message key="pone.title" bundle="xxx"/> </title>
</head>
<body>
<bean:message key="pone.lone" bundle="xxx"/> <br>
<bean:message key="pone.ltwo" bundle="xxx"/> <br>
<bean:message key="pone.lthr" bundle="xxx"/> <br>
</body>
</html>
http://localhost:7001/i18n/pone.jsp
welcome to our web app
line two of pone in
line three of pone in

 If there is more number of resources in a properties file then it will be typical to


manage. In this case it is better to go for multiple sets of properties files as shown below.

 one.rone=value of one.rone
one.rtwo=value of one.rtwo resone.properties
one.rthr=value of one.rthr
Set I
 one.rone=value of one.rone in fr
one.rtwo=value of one.rtwo in fr resone_fr_CA.properties
one.rthr=value of one.rthr in fr

 two.rone=value of two.rone
two.rtwo=value of two.rtwo restwo.properties
two.rthr=value of two.rthr
Set II
 two.rone=value of two.rone in fr
two.rtwo=value of two.rtwo in fr restwo_fr_CA.properties
two.rthr=value of two.rthr in fr

Struts-config.xml must be configured as shown below for using the above two Sets.

 <message-resources parameter="resone"/>
<message-resources key="xxx" parameter="restwo"/>

SUDHEER REDDY
17
POTHURAI
 <%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<bean:message key="one.rone"/> <br>
<bean:message key="one.rtwo"/> <br>
<bean:message key="one.rthr"/> <br>
<bean:message key="two.rone" bundle="xxx"/> <br>
<bean:message key="two.rtwo" bundle="xxx"/> <br>
<bean:message key="two.rthr" bundle="xxx"/> <br>
http://localhost:7001/i18n/test.jsp
value of one.rone
value of one.rtwo
value of one.rthr
value of two.rone
value of two.rtwo
value of two.rthr

 Select the language French (Canada) [fr-ca] in the internet explorer.


http://localhost:7001/i18n/test.jsp
value of one.rone in fr
value of one.rtwo in fr
value of one.rthr in fr
value of two.rone in fr
value of two.rtwo in fr
value of two.rthr in fr

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


<bean:message key="one.rfour"/> <br> non existing resources
<bean:message key="two.rfour" bundle="xxx"/> <br>
http://localhost:7001/i18n/test.jsp
Error 500--Internal Server Error
javax.servlet.jsp.JspException: Missing message for key "one.rfour"

if non existing resources are used an exception may be thrown or a String will be sent
to the browser indicating at the value is not known (???fr_CA.one.rfour???, ???
fr_CA.two.rfour???)

An exception will be thrown if the properties if the properties fill are configured as
shown below
<message-resources parameter="resone"/>
<message-resources key="xxx" parameter="restwo"/>

A String will be sent to the browser with question marks (?), if the properties fill is
configured as shown below
<message-resources parameter="resone" null="false"/>
<message-resources key="xxx" parameter="restwo" null="false"/>
http://localhost:7001/i18n/test.jsp
???fr_CA.one.rfour???
???fr_CA.two.rfour???

SUDHEER REDDY
18
POTHURAI
 <%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%
request.setAttribute("xxx","aaaa");
%>
<logic:present name="xxx" scope="request">
--------
</logic:present>
<logic:notPresent name="xxx" scope="request">
********
</logic:notPresent>
http://localhost:7001/i18n/pre.jsp
--------

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


<logic:present name="xxx" scope="request">
--------
</logic:present>
<logic:notPresent name="xxx" scope="request">
********
</logic:notPresent>
http://localhost:7001/i18n/pre.jsp
********
 We can use the code shown below to check whether the MessageResources are
loaded with the default key.

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


<logic:notPresent scope="application" name="org.apache.struts.action.MESSAGE" >
ERROR---- message resources are not loaded
********
</logic:notPresent>
<logic:present scope="application" name="org.apache.struts.action.MESSAGE" >
message resources are available
</logic:present>
http://localhost:7001/i18n/mrpre.jsp
message resources are available

ActionErrors & ActionError: - ActionError object represents single error. ActionErrors


object represents multiple errors.

ActionError

ActionErrors
ActionError

SUDHEER REDDY
19
POTHURAI
Ex: - ActionError ae1, ae2;
ae1=new ActionError(“eone.msg”); key of the Error message
ae2=new ActionError(“etwo.msg”);
ActionErrors aes=new ActionErrors( );
aes.add(“propOne”,ae1); Property name
aes.add(“propTwo”,ae2);

Note: - The information about the error messages must be provided in the properties files
as shown below.

 eone.msg=Error Message one


etwo.msg=Error Message two messageResources.properties

 eone.msg=Error Message one in fr


etwo.msg=Error Message two in fr messageResources_fr_CA.properties

 Struts-config.xml must be configured as shown below.


 <message-resources parameter="messageResources"/>
 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class TEAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
ActionErrors aes=new ActionErrors( );
ActionError ae1,ae2,ae3;
System.out.println("---aes-1-->"+aes.size( ));
ae1=new ActionError("eone.msg");
aes.add("propOne",ae1);
ae2=new ActionError("etwo.msg");
aes.add("propTwo",ae2);
ae3=new ActionError("ethr.msg");
aes.add("propThr",ae3);
System.out.println("---aes-2-->"+aes.size( ));
saveErrors(request,aes);
return mapping.findForward("disperrs");
}
}
D:\Pskr\Struts>javac TEAction.java
saveErrors( )method stores the ActionErrors object in the request object.
 Struts-config.xml must be configured as shown below.
 <action-mappings>
<action path="/er" type="TEAcion">
<forward name="disperrs" path="/de.jsp"/>
</action>
</action-mappings>

SUDHEER REDDY
20
POTHURAI
<%@ taglib uri="/tags/struts-html" prefix="html" %>
List of Error Messages <br>
<html:errors />
http://localhost:8000/err/er.do
---aes-1-->0
---aes-2-->3
List of Error Messages
• Error Message one
• Error Message two

 Select the language French (Canada) [fr-ca] in the internet explorer.
http://localhost:8000/err/er.do
---aes-1-->0
---aes-2-->3
List of Error Messages
• Error Message one in fr
• Error Message two in fr

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


List of Error Messages <br>
<html:errors property="propOne"/>
----------------<br>
<html:errors property="propTwo"/>
http://localhost:8000/err/er.do
---aes-1-->0
---aes-2-->3
List of Error Messages
• Error Message one in fr
----------------
• Error Message two in fr

The errors tag generates the list of error messages using ActionError objects
available in ActionErrors object which is available in request object.
Problem: - The error tag internally uses the following four resources will generating the
list of errors.
errors.header=<UL>
errors.prefix=<LI>
errors.suffix=</LI>
errors.footer=</UL>
The errors tag forces us to add the html tags to the properties files. Adding the
html tags to the properties file is not a good practice.

 As an alternative for errors tag, Struts team has provided messages tag. For using
messages tag we need to use the html tags in the property files.

SUDHEER REDDY
21
POTHURAI
 <%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
List of Error Messages <br>
<html:messages id="msg">
<bean:write name="msg"/> <br>
</html:messages>
http://localhost:8000/err/er.do
---aes-1-->0
---aes-2-->3
List of Error Messages

Error Message one in fr


Error Message two in fr

 ActionError object can be used to represent an error message. But as part of our
project we may be using several messages. Some of these messages may not be error
messages. For representing error messages as well as other messages we can use
ActionMessage object. ActionMessage is provided as an alternative for ActionError.
ActionMessages is provided in an alternative for ActionErrors. saveMessages is provided
is an alternative for saveError( ) method.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class MTEAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
ActionMessages ams=new ActionMessages( );
ActionMessage am1,am2,am3;
System.out.println("---ams-1-->"+ams.size( ));
am1=new ActionMessage("eone.msg");
ams.add("propOne",am1);
am2=new ActionMessage("etwo.msg");
ams.add("propTwo",am2);
am3=new ActionMessage("ethr.msg");
ams.add("propThr",am3);
System.out.println("---ams-2-->"+ams.size( ));
saveMessages(request,ams);
return mapping.findForward("disperrs");
}
}
D:\Pskr\Struts>javac MTEAction.java

 Struts-config.xml must be configured as shown below.


 <action-mappings>
<action path="/mer" type="MTEAcion">

SUDHEER REDDY
22
POTHURAI
<forward name="disperrs" path="/mde.jsp"/>
</action>
</action-mappings>

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


<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
List of Error Messages <br>
<html:messages id="msg" message="true">
<bean:write name="msg"/> <br>
</html:messages>
http://localhost:8000/err1/mer.do
---ams-1-->0
---ams-2-->3
List of Error Messages

Error Message one in fr


Error Message two in fr
 Select the language English (United States) [en-US] in the internet explorer.
http://localhost:8000/err1/mer.do
---ams-1-->0
---ams-2-->3
List of Error Messages

Error Message one


Error Message two

To generate the messages that are stored inside ActionMessages object, we can use the
code shown above.
Message tag is deal with ActionError & ActionErrors, ActionMessage &
ActionMessages. This is the advantage of message tag.

 SQL> create table product (pid number(4) primary key, pname varchar(10), price
number(10,2));
Table created.
SQL> desc product
Name Null? Type
----------------------------------------- -------- ----------------------------
PID NOT NULL NUMBER(4)
PNAME VARCHAR2(10)
PRICE NUMBER(10,2)

SQL> commit;
Commit complete.

SQL> select * from product;


no rows selected

SUDHEER REDDY
23
POTHURAI

Strut forms: -
Procedure for dealing with the forms in a struts based application: -
Step 1: - We must decide about the name of the form, the names of the fields in the forms,
the validation rules for validating the data provided in the fields.
Product Id: prodId
Product Name: prodName
Price: prodPrice

Form Name: NewProdForm


Validation rules: -
1) prodId is required
2) prodId must be an Integer
3) prodName is required
4) prodPrice is required
5) prodPrice must be float

Step 2: - Provide a form bean class


A sub class of ActionForm class is called as a form bean class.

ActionForm
……….
reset(..)
validate(..)

extends extends
NewProdFB SomeOtherFB

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class NewProdFB extends ActionForm
{
public void NewProdFB( )
{
System.out.println("----NewProdFB created----");
}
private String prodId;
private String prodName;
private String prodPrice;
// getters & setters
public void setProdId(String prodId)
{

SUDHEER REDDY
24
POTHURAI
System.out.println("----setProdId---->"+prodId);
this.prodId=prodId;
}
public String getProdId( )
{
System.out.println("----getProdId---->"+this.prodId);
return this.prodId;
}
public void setProdName(String prodName)
{
System.out.println("----setProdName---->"+prodName);
this.prodName=prodName;
}
public String getProdName( )
{
System.out.println("----getProdName---->"+this.prodName);
return this.prodName;
}
public void setProdPrice(String prodPrice)
{
System.out.println("----setProdPrice---->"+prodPrice);
this.prodPrice=prodPrice;
}
public String getProdPrice( )
{
System.out.println("----getProdPrice---->"+this.prodPrice);
return this.prodPrice;
}
// reset method
public void reset(ActionMapping mapping, HttpServletRequest request)
{
this.prodId="100";
this.prodName="xyz";
this.prodPrice="100.01";
}
// validate method
public ActionErrors validate(ActionMapping mapping, HttpServletRequest
request)
{
ActionErrors aes=new ActionErrors( );
System.out.println("---Size--1-->"+aes.size( ));
if((this.prodId==null) || (this.prodId.equals("")))
{
ActionError ae=new ActionError("prodId.req");
aes.add("prodId",ae);
}
else

SUDHEER REDDY
25
POTHURAI
{
try
{
Integer.parseInt(this.prodId);
}
catch(Exception e)
{
ActionError ae=new ActionError("prod.not.int");
aes.add("prodId",ae);
}
}
if((this.prodName==null) || (this.prodName.equals("")))
{
ActionError ae=new ActionError("prodName.req");
aes.add("prodName",ae);
}
if((this.prodPrice==null) || (this.prodPrice.equals("")))
{
ActionError ae=new ActionError("prodPrice.req");
aes.add("prodPrice",ae);
}
else
{
try
{
Float.parseFloat(this.prodPrice);
}
catch(Exception e)
{
ActionError ae=new ActionError("prod.not.float");
aes.add("prodPrice",ae);
}
}
System.out.println("---Size--2-->"+aes.size( ));
return aes;
}
}
D:\Pskr\Struts>javac SPDAction.java

Note: - As part of the reset( ) method code must be provided for setting the default values
of various fields of the form. As part of the validate( ) method we must provide the code
to check whether the data provided by the user is valid or not.

Step 3: - Provide the action class

 import javax.servlet.http.*;
import org.apache.struts.action.*;

SUDHEER REDDY
26
POTHURAI
import java.sql.*;
public class SPDAction extends Action
{
public SPDAction( )
{
System.out.println("----SPDAction created----");
}
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
NewProdFB fb=(NewProdFB)form;
// code to strore data in DB
String pid=fb.getProdId( );
String pname=fb.getProdName( );
String price=fb.getProdPrice( );
// code to connect DB
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
String vsql="insert into product values(?,?,?)";
PreparedStatement pstmt=con.prepareStatement(vsql);
pstmt.setString(1,pid);
pstmt.setString(2,pname);
pstmt.setString(3,price);
pstmt.executeUpdate( );
con.close( );
return mapping.findForward("pds");
}
}
D:\Pskr\Struts>javac SPDAction.java

Step 4: - Provide a JSP that generates the input form

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


<% System.out.println("-----npform.jsp------"); %>
<html:html locale="true">
<head> <title> New Product Data </title> </head>
<body>
<html:errors />
<html:form action="/spd.do">
Prod Id :
<html:text property="prodId"/> <br>
Prod Name :
<html:text property="prodName"/> <br>
Price :
<html:text property="prodPrice"/> <br>
<html:submit property="submit" value="store"/> <br>

SUDHEER REDDY
27
POTHURAI
</html:form>
</body>
</html:html>

Step 5: - Provide the information about form bean & the action in struts-config.xml

 <form-beans>
<form-bean name="NewProdForm" type="NewProdFB"/>
</form-beans>
<action-mappings>
<action name="NewProdForm" input="/npform.jsp" path="/spd"
validate="true" scope="request" type="SPDAction">
<forward name="pds" path="/pds.jsp"/>
</action>
</action-mappings>

Step 6: - Provide the pds.jsp

 <% System.out.println("-- executing pds.jsp--"); %>


data stored into db

Step 7: - Provide the information about errors in properties file

 prodId.req=prodId is must be required


prod.not.int=prodId is must be an integer
prodName.req=prodName is must be required
prodPrice.req=prodPrice is must be required
prod.not.float=prodPriceId is must be an float
http://localhost:8000/form/npform.jsp
----getProdId---->100
----getProdName---->xyz
----getProdPrice---->100.01
Prod Id :
Prod Name : Default values
Price :

Prod Id :
Prod Name :
Price :
Click
----setProdId---->abc
----setProdName---->
----setProdPrice---->xyz
---Size--1-->0
---Size--2-->3
----npform.jsp----
----getProdId---->abc

SUDHEER REDDY
28
POTHURAI
----getProdName---->
----getProdPrice---->xyz

• prodId is must be an integer


• prodName is must be required
• prodPriceId is must be an float

Prod Id :
Prod Name :
Price :
Click
----setProdId---->
----setProdName---->abc
----setProdPrice---->
---Size--1-->0
---Size--2-->2
----npform.jsp----
----getProdId---->
----getProdName---->abc
----getProdPrice---->

• prodId is must be required


• prodPrice is must be required

Prod Id :
Prod Name :
Price :
Click
----setProdId---->34
----setProdName---->abc
----setProdPrice---->1234
---Size--1-->0
---Size--2-->0
----SPDAction created----
----getProdId---->34
----getProdName---->abc
----getProdPrice---->1234
-- executing pds.jsp--
data stored into db
SQL> select * from product;
PID PNAME PRICE
--------------- -------------------- -----------------
34 abc 1234

 <html:html locale="true">
---------<br>
</html:html>

SUDHEER REDDY
29
POTHURAI
When the html tag of struts-html tag libraries is evaluated, its generates the html
tag shown below
<html lang="fr">
---------<br>
</html>

 <html:form action="/spd.do">
</html:form>
When the above form tag is evaluated the following steps will be performed.
1) The name of the form bean class will be obtained.
2) If required the object will be created using the form bean class, the reset( ) method
will be called. The form bean object will be stored either in the session or in the
request.
3) Generates the form tag as shown below.
<form name="NewProdForm" method="post" action="/form/spd.do">
</form>

 <html:text property="prodId"/>
When the above text tag is evaluated the following steps will be carried out.
1) getProdId( ) method will be executed on the form bean object.
2) Generates the input tag as shown below.
<input type="text" name="prodId" value="100">
Value returned by getProdId( ) method
 <html:submit property="submit" value="store"/>
When the above tag is evaluated, its generates the html tag shown below
<input type="submit" name="submit" value="store">
 <% System.out.println("----eh.jsp----"); %>
Please read the code once again.

 Provide the information in struts-config.xml


<action name="NewProdForm" input="/eh.jsp" path="/spd" validate="true"
scope="request" type="SPDAction">
http://localhost:8000/form/npform.jsp
Prod Id :
Prod Name :
Price :
Click
----eh.jsp----
Please read the code once again.

When we enter the wrong values in the fields and click the store button, eh.jsp is
executed (specified in input attribute). When we enter the correct values in the fields and
click the store button, SPDAction is executed (specified in type attribute).

 If scope is set to request (in action tag of struts-config.xml), Struts code places the form
bean in the request object. If scope is set to session, form bean will be stored inside the
session object.

SUDHEER REDDY
30
POTHURAI

 If validate is set to true, Struts code calls the validate( ) method & the validations will
be carried out in the server. This is called as server side validations.
Server side validations put more burdens on the server. To reduce burdens on the
server we can use java script to validate the data in the client.
http://localhost:8000/form/spd.do
Prod Id :
Prod Name :
Price :
Click
----setProdId---->
----setProdName---->
----setProdPrice---->
---Size--1-->0
---Size--2-->3
----eh.jsp----

 When we can use client side validations, we can switch off the server side
validations. For this we can set validate="false";
http://localhost:8000/form/spd.do
Prod Id :
Prod Name :
Price :
Click
----setProdId---->
----setProdName---->
----setProdPrice---->
----SPDAction created----

 In majority of cases client side validations provides bettor performance. In some of the
cases we may need to transfer lot of data as part of the java script to take care of
validations in the client. Transferring more amounts of data reduces the performance. In
this kind of cases we can prefer server side validations.

Capture the data provided by the user

not valid valid


Is data valid?

Re display the form with Process the data according to


errors the business requirements.

SUDHEER REDDY
31
POTHURAI
The above flow chart shows the steps that are typically performed by an
application while dealing with a form.
The frame works like struts, springs supports the same set of steps.

Struts capture the data. Creates a form bean (if required)


object, calls reset, and stores FB in request / session. Calls
setters on FB to store the capture data in data

What is the value of


validate? false

true

Struts calls validate


method on FB object

Any errors reported


yes by the validate no
method?

Struts forward the request to Struts calls execute ( )


the resource specified in input method on action object for
atrribute processing the data

ActionForm
reset
validate
…….

extends

DynaActionForm
set (..)
get(.)

extends

SUDHEER REDDY
32
POTHURAI

OurOwnFB
We need to provide getters & setters

SQL> create table employee(uname varchar(15),pwd varchar(10),age number(3), email


varchar(25));
Table created.
SQL> select * from employee;
no rows selected
Procedure for using DynaActionForm to deal (handle) a form: -
Step 1: - We must decide about the name of the form, the names of the fields in the form
and the validations rules that must be applied on various fields of the form.

User Name : userName


Password : pwd
Age : age
Email : email

Form name: UserRegForm


Validations: -
1) userName is required.
2) pwd is required.
3) min length of username must be 5 chars.
Step 2: - Create the form bean class as a sub class of DynaActionForm class

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class DUserRegFB extends DynaActionForm
{
public void reset(ActionMapping mapping,HttpServletRequest request)
{
System.out.println("----reset----");
set("userName","your name");
set("pwd","");
set("age","21");
set("email",null);
}
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request)
{
System.out.println("----validate----");
String userName,pwd;
userName=(String)get("userName");
pwd=(String)get("pwd");

SUDHEER REDDY
33
POTHURAI
ActionErrors aes=new ActionErrors( );
if(userName==null || userName.equals(""))
{
ActionError ae=new ActionError("uname.req");
aes.add("userName",ae);
}
else
{
if(userName.length( )<5)
{
ActionError ae=new ActionError("uname.ml.err");
aes.add("userName",ae);
}
}
if(pwd==null || pwd.equals(""))
{
ActionError ae=new ActionError("pwd.req");
aes.add("pwd",ae);
}
return aes;
}
}
D:\Pskr\Struts>set CLASSPATH=.;struts.jar;servlet-api.jar;commons-beanutils.jar
D:\Pskr\Struts>javac DUserRegFB.java

Step 3: - Provide the information about form bean in struts-config.xml

 <form-beans>
<form-bean name="UserRegForm" type="DUserRegFB">
<form-property name="userName" type="java.lang.String"/>
<form-property name="pwd" type="java.lang.String"/>
<form-property name="age" type="java.lang.String"/>
<form-property name="email" type="java.lang.String"/>
</form-bean>
</form-beans>

Step 4: - Provide the action class RUAction

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
public class RUAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----RUAction.execute----");

SUDHEER REDDY
34
POTHURAI
DUserRegFB fb=(DUserRegFB)form;
String vuname=(String)fb.get("userName");
String vpwd=(String)fb.get("pwd");
String vage=(String)fb.get("age");
String vemail=(String)fb.get("email");
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
String vsql="insert into employee values(?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(vsql);
pstmt.setString(1,vuname);
pstmt.setString(2,vpwd);
pstmt.setString(3,vage);
pstmt.setString(4,vemail);
pstmt.executeUpdate( );
con.close( );
return mapping.findForward("userregd");
}
}
D:\Pskr\Struts>javac RUAction.java

Step 5: - Provide the JSP that generates the input form.

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


<% System.out.println("----urform.jsp----"); %>
<html:html locale="true">
<head> <title> Register Data </title> </head>
<body>
<html:errors />
<html:form action="/ur.do">
User Name :
<html:text property="userName"/> <br>
Password :
<html:password property="pwd"/> <br>
Age :
<html:text property="age"/> <br>
Email :
<html:text property="email"/> <br>
<html:submit property="submit" value="register"/> <br>
</html:form>
</body>
</html:html>

Step 6: - Provide the information about ActionMapping in struts-config.xml

 <action-mappings>

SUDHEER REDDY
35
POTHURAI
<action name="UserRegForm" input="/urform.jsp" path="/ur" validate="true"
scope="request" type="RUAction">
<forward name="userregd" path="/ur.jsp"/>
</action>
</action-mappings>

Step 7: - Provide the ur.jsp

 <% System.out.println("-- executing ur.jsp--"); %>


user info registered

Step 8: - Provide the information about errors in properties file

 uname.req=user name must be required


uname.ml.err=minimum length of user name must be 5 characters
pwd.req=password must be required
http://localhost:8000/daform/urform.jsp
----urform.jsp----
----reset----
User Name :
Password :
Age :
Email :

User Name :
Password :
Age :
Email :
Click
----reset----
----validate----
----urform.jsp----

• user name must be required


• password must be required

User Name :
Password :
Age :
Email :
Click
----reset----
----validate----
----urform.jsp----

• minimum length of user name must be 5 characters

SUDHEER REDDY
36
POTHURAI
User Name :
Password :
Age :
Email :
Click
----reset----
----validate----
----RUAction.execute----
-- executing ur.jsp--
user info registered
SQL> select * from employee;
UNAME PWD AGE EMAIL
--------------- ---------- ---------- ----------------------------
abcde Sunil 25 sudheer_1620@yahoo.com

Spell checker

Plug-in

OurNp
 A plug-in is additional software that is used to enhance the capabilities of the
existing software. Any one can develop a plug-in for struts frame work. As part of struts
1.1 to standard plug-ins are provided.
1) Struts validator plug-in
2) Struts tiles plug-in
The information about the plug-in must be provided in struts-config.xml using the plug-
in tag
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
-------------
</plug-in>
ValidatorPlugIn uses the information available in the files validator-rules.xml,
validation.xml.

 DynaValidatorForm provides the feature available as part of DynaActionForm & this


class will be able to take care of the validations automatically.

 SQL> create table students(sid number(8),sname varchar(15),fname varchar(15), addr


varchar(20),age number(3));
Table created.
SQL> select * from students;
no rows selected

Procedure for implementing the application using DynaValidatorForm: -

SUDHEER REDDY
37
POTHURAI
Step 1: - We must decide about the name of the form, the names of the fields in the form
and the validations rules that must be applied on various fields of the form.
Student Id: studId
Student Name: studName
Father Name: fatherName
Address : addr
Age: age

Form name: NewStudForm


Validation rules: -
1) studId is required.
2) studName is required.
3) age is required.
4) age must be between 15 & 45.
5) addr is required

Step 2: - Create the form bean class as a sub class of DynaActionForm class.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.validator.*;
public class DVStudFB extends DynaValidatorForm
{
public void reset(ActionMapping mapping,HttpServletRequest request)
{
System.out.println("----reset----");
set("age",new java.lang.Integer(21));
}
}
D:\Pskr\Struts>set CLASSPATH=.;struts.jar;servlet-api.jar;commons-beanutils.jar
D:\Pskr\Struts>javac DVStudFB.java

Step 3: - Provide the information about the form bean in struts-config.xml

 <form-beans>
<form-bean name="NewStudForm" type="DVStudFB">
<form-property name="studId" type="java.lang.String"/>
<form-property name="studName" type="java.lang.String"/>
<form-property name="fatherName" type="java.lang.String"/>
<form-property name="addr" type="java.lang.String"/>
<form-property name="age" type="java.lang.Integer"/>
</form-bean>

SUDHEER REDDY
38
POTHURAI
</form-beans>

Step 4: - Provide the action class

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
public class SSDAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----SSDAction.execute----");
DVStudFB fb=(DVStudFB)form;
String vstudId=(String)fb.get("studId");
String vstudName=(String)fb.get("studName");
String vfatherName=(String)fb.get("fatherName");
String vaddr=(String)fb.get("addr");
String vage=(String)fb.get("age");
// code to store student's data in DB
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
String vsql="insert into students values(?,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(vsql);
pstmt.setString(1,vstudId);
pstmt.setString(2,vstudName);
pstmt.setString(3,vfatherName);
pstmt.setString(4,vaddr);
pstmt.setString(5,vage);
pstmt.executeUpdate( );
con.close( );
return mapping.findForward("sds");
}
}
D:\Pskr\Struts>javac SSDAction.java

Step 5: - Provide the JSP that generates the input form nsform.jsp

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


<% System.out.println("----nsform.jsp----"); %>
<html:html locale="true">
<head> <title> Store Data </title> </head>
<body>
<html:errors />
<html:form action="/ssd.do">
Student Id:

SUDHEER REDDY
39
POTHURAI
<html:text property="studId"/> <br>
Student Name:
<html:text property="studName"/> <br>
Father Name:
<html:text property="fatherName"/> <br>
Address :
<html:text property="addr"/> <br>
Age:
<html:text property="age"/> <br>
<html:submit property="submit" value="store"/> <br>
</html:form>
</body>
</html:html>

Step 6: - provide the information about the action in struts-config.xml


 <action-mappings>
<action name="NewStudForm" input="/nsform.jsp" path="/ssd"
validate="true" scope="request" type="SSDAction">
<forward name="sds" path="/sds.jsp"/>
</action>
</action-mappings>

Step 7: - Provides the errors in properties file


 Address=----Address----
Step 8: - Provide the sds.jsp

 <% System.out.println("-- executing ssd.jsp--"); %>


Student's data stored

Step 9: - Provide the information about the validations that has to be performed on
various fields in the file validation.xml

 <formset>
<form name="NewStudForm">
<field property="studId" depends="required">
<arg0 name="required" key="Student Id" resource="false"/>
</field>
<field property="studName" depends="required">
<arg0 name="required" key="Student Name" resource="false"/>
</field>
<field property="addr" depends="required">
<arg0 name="required" key="Address" resource="true"/>
</field>
<field property="age" depends="required,intRange">
<arg0 name="required" key="Age" resource="false"/>
<arg0 name="intRange" key="Age" resource="false"/>
<arg1 name="intRange" key="${var:min}" resource="false"/>

SUDHEER REDDY
40
POTHURAI
<arg2 name="intRange" key="${var:max}" resource="false"/>
<var>
<var-name>min</var-name>
<var-value>15</var-value>
</var>
<var>
<var-name>max</var-name>
<var-value>45</var-value>
</var>
</field>
</form>
</formset>
http://localhost:8000/dvaform/nsform.jsp
----nsform.jsp----
----reset----
Student Id:
Student Name:
Father Name:
Address :
Age:

Student Id:
Student Name:
Father Name:
Address :
Age:
Click
----reset----
----nsform.jsp----

• Student Id is required.
• Student Name is required.
• ----Address---- is required.
• Age is not in the range 15 through 45.

Student Id:
Student Name:
Father Name:
Address :
Age:
Click
----reset----
----SSDAction.execute----
-- executing ssd.jsp--
Student's data stored
SQL> select * from students;
SID SNAME FNAME ADDR AGE

SUDHEER REDDY
41
POTHURAI
---------- --------------- --------------- ----------------------- -------------
630130 sudheer kesav nrp 24

 pmsg.one=copying {0} to {1}


pmsg.two=Hello {0} MessageResources.properties

param0/ arg0 param1/ arg1

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


<bean:message key="pmsg.one" /> <br>
<bean:message key="pmsg.two" />
http://localhost:8000/dvaform/eh.jsp
copying null to null
Hello null

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


<bean:message key="pmsg.one" arg0="xxx.txt" arg1="yyy.txt"/> <br>
<bean:message key="pmsg.one" arg0="abc.txt" arg1="xyz.txt"/> <br>
<bean:message key="pmsg.two" arg0="Sudheer"/>
http://localhost:8000/dvaform/eh.jsp
copying xxx.txt to yyy.txt
copying abc.txt to xyz.txt
Hello Sudheer

The validator required uses the error message errors.required={0} is required & the
validator int range uses the error message errors.range={0} is not in the range {1} through
{2}.
Some of the validators use the variables. min, max are the variables used by the
validators intRange, floatRange, doubleRange.

 We can configure the byte validator on a field as shown below


<field property="age" depends="byte">
<arg0 name="byte" key="Age" resource="false"/>
</field>

 minLength, maxLength validators can be configured as shown below


<field property="studName" depends="required,minlength,maxlength">
<arg0 key="Student Name" resource="false"/>
<arg1 name="minlength" key="${var:minlength}" resource="false"/>
<arg1 name="maxlength" key="${var:maxlength}" resource="false"/>
<var>
<var-name>minlength</var-name>
<var-value>5</var-value>
</var>
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>

SUDHEER REDDY
42
POTHURAI
</var>
</field>

 Date validator supports 2 variables datePattern, datePatternStrict


<field property="studId" depends="required,date">
<arg0 key="Student Id" resource="false"/>
<var>
<var-name>datePatternStrict</var-name>
<var-value>dd/MM/yyyy</var-value>
</var>
</field>

Date validator treats 1/01/2001 & 1/1/01 as valid values if we use datePattern.
1/01/2001 & 1/1/01 is considered as invalid when we configured the date validator with the
variable datePatternStrict.

http://localhost:8000/dvaform/form.jsp
Student Id:
Student Name:
Age:
Click

• Student Id is not a date.


• Student Name can not be less than 5 characters.
• Age must be a byte.

Student Id:
Student Name:
Age:
Click

• Student Name can not be greater than 10 characters.

Student Id:
Student Name:
Age:
Click
Data stored

 Mask validator uses the variable with the name mask. The value we provide for this
variable is called as a regular expression.

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


<% System.out.println("----form.jsp----"); %>
<html:html locale="true">
<head> <title> Store Id </title> </head>
<body>

SUDHEER REDDY
43
POTHURAI
<html:errors />
<html:form action="/ssd.do">
Student Id:
<html:text property="studId"/> <br>
<html:submit property="submit" value="store"/> <br>
</html:form>
</body>
</html:html>
 <formset>
<form name="NewStudForm">
<field property="studId" depends="required,mask">
<arg0 key="Student Id" resource="false"/>
<var>
<var-name>mask</var-name>
<var-value>xyz</var-value>  ©
</var> Regular expression
</field>
</form>
</formset>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is required.

Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
The regular expression xyz matches with any string that contains xyz in a sequence. xyz,
aaxyz, xyzbb, wwwxyzmm – matches with the regular expression xyz.

©  <var-value>^xyz$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored

SUDHEER REDDY
44
POTHURAI
The above regular expression accepts xyz only. Here ^ means starts with, $ means ends
with.
©  <var-value>^x[a-zA-Z0-9]z$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
Student Id:
Click
Data stored
Student Id:
Click
Data stored
The above regular expression allows any character between a to z, A to Z, 0 to 9.

©  <var-value>^x(a|f|m)z$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
Student Id:
Click
Data stored
The above regular expression allows a or f or m as second char in the input.

©  <var-value>^[0-9][0-9][0-9]( |-)[0-9][0-9][0-9]$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click
Data stored
Student Id:
Click
Data stored
We can use ^[0-9][0-9][0-9]( |-)[0-9][0-9][0-9]$ as a regular expression to accept the pin
code as shown below.
500 007, 500-007, 100-001 etc.

SUDHEER REDDY
45
POTHURAI
©  <var-value>^[0-9]{11}$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
The above regular expression accepts exactly 11 digits.

©  <var-value>^[0-9]{10,12}$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
The above regular expression accepts minimum 10 digits, maximum 12 digits.

©  <var-value>^[0-9]{5,}$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
The above regular expression accepts minimum 5 digits, maximum no limit.

©  <var-value>^xa?z$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored

SUDHEER REDDY
46
POTHURAI
Student Id:
Click
Data stored
Here ? means zero or one.
+ ----> one are more
* ----> zero are more

©  <var-value>^x\d\Dz$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click

• Student Id is invalid

Student Id:
Click
Data stored
\d ----> allow digit.
\D ----> allows anything other than a digit.
\s ----> allows white space.
\S ----> allows anything other than a white space.
\w ----> allow word chars.
\W ----> allows anything other than a word chars.
. ----> matches with anything other than new line.
Note: - Alphabets, digits, underscore( _ ) are called as a word characters.
 To remove a special meaning of meta characters a slash(\) can be used before the
character.

©  <var-value>^[A-Z]\.[A-Z][a-z]{2,10}$</var-value>
http://localhost:8000/dvaform/form.jsp
Student Id:
Click
Data stored
Student Id:
Click
Data stored

 Struts validator plug-in will be able to generate the java script to validate the inputs in
the clients. For generating the java script we must used the java script tag of struts-html
tag library.
<html:javascript formName="NewStudForm"/>
The above tag sends a java script to the browser. This java script contains a function
with the name validateNewStudForm. But this function is not executed automatically. We
must provide the code to call this function when user submits the form. For this we can
provide the code as shown below.
 <%@ taglib uri="/tags/struts-html" prefix="html"%>
<% System.out.println("----nsform.jsp----"); %>

SUDHEER REDDY
47
POTHURAI
<html:html locale="true">
<head> <title> Register Data </title> </head>
<body>
<html:javascript formName="NewStudForm"/>
<html:errors />
<html:form action="/ssd.do" onsubmit="return
validateNewStudForm(this);">
Student Id:
<html:text property="studId"/> <br>
Student Name:
<html:text property="studName"/> <br>
Father Name:
<html:text property="fatherName"/> <br>
Address :
<html:text property="addr"/> <br>
Age:
<html:text property="age"/> <br>
<html:submit property="submit" value="store"/> <br>
</html:form>
</body>
</html:html>
 <action-mappings>
<action name="NewStudForm" input="/nsform.jsp" path="/ssd"
validate="false" scope="request" type="SSDAction">
<forward name="sds" path="/sds.jsp"/>
</action>
</action-mappings>

 SQL> select * from students;


no rows selected

http://localhost:8000/dvaform/nsform.jsp
Student Id:
Student Name:
Father Name:
Address :
Age:
Click

SUDHEER REDDY
48
POTHURAI
Student Id:
Student Name:
Father Name:
Address :
Age:
Click

Student Id:
Student Name:
Father Name:
Address :
Age:
Click
Student's data stored
SQL> select * from students;
SID SNAME FNAME ADDR AGE
----------------- ------------- --------------------- ------------------ ------------------
630130 Sunil Kesav Anantapur 25

 How to take care of validations that can not be carried out by struts?
A)
 SQL> create table users(uname varchar(15), pone varchar(10), ptwo varchar(10));
Table created.
SQL> select * from users;
no rows selected
Step 1: -
UserName: userName
Password: pwdOne
re-type Password: pwdTwo

Form name: NewUserAccForm


Validations: -
1) userName is required.
2) pwdOne is required.
3) pwdTwo is required.
4) pwdOne must be same as pwdTwo.
Assumption: - 4th validation can not be carried out by struts.

SUDHEER REDDY
49
POTHURAI
Step2: - Create the form bean class as a sub class of DynaValidatorForm class

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.validator.*;
public class DVNUsrFB extends DynaValidatorForm
{
public void reset(ActionMapping mapping,HttpServletRequest request)
{
set("userName","");
set("pwdOne","");
set("pwdTwo","");
}
public ActionErrors validate(ActionMapping mapping,HttpServletRequest
request)
{
ActionErrors aes=super.validate(mapping,request);
System.out.println("---aes--1-->"+aes.size( ));
String vpwdOne=(String)get("pwdOne");
String vpwdTwo=(String)get("pwdTwo");
if(!vpwdOne.equals(vpwdTwo))
{
aes.add("pwdOne",new ActionError("pwds.not.equals"));
}
System.out.println("---aes--2-->"+aes.size( ));
return aes;
}
}
D:\Pskr\Struts>javac DVNUsrFB.java
The validate( ) method in the super class DynaValidatorForm takes care of validations
that are specified in validation.xml.

Step3: - Provide the information about the form bean in struts-config.xml

 <form-beans>
<form-bean name="NewUserAccForm" type="DVNUsrFB">
<form-property name="userName" type="java.lang.String"/>
<form-property name="pwdOne" type="java.lang.String"/>
<form-property name="pwdTwo" type="java.lang.String"/>
</form-bean>
</form-beans>

Step4: - Provides the errors in properties file

 pwds.not.equals=Passwords must be same

Step5: - Provide the action class

SUDHEER REDDY
50
POTHURAI

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
public class CUAAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----CUAAction.execute----");
DVNUsrFB fb=(DVNUsrFB)form;
String vuserName=(String)fb.get("userName");
String vpwdOne=(String)fb.get("pwdOne");
String vpwdTwo=(String)fb.get("pwdTwo");
// code to store student's data in DB
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
String vsql="insert into users values(?,?,?)";
PreparedStatement pstmt=con.prepareStatement(vsql);
pstmt.setString(1,vuserName);
pstmt.setString(2,vpwdOne);
pstmt.setString(3,vpwdTwo);
pstmt.executeUpdate( );
con.close( );
return mapping.findForward("uacreated");
}
}
D:\Pskr\Struts>javac CUAAction.java

Step6: - Provide the JSP that generates the input form nuform.jsp

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


<% System.out.println("----nuform.jsp----"); %>
<html:html locale="true">
<head> <title> User Created </title> </head>
<body>
<html:errors />
<html:form action="/cua.do">
UserName:
<html:text property="userName"/> <br>
Password:
<html:password property="pwdOne"/> <br>
re-type Password:
<html:password property="pwdTwo"/> <br>
<html:submit property="submit" value="Create"/> <br>
</html:form>

SUDHEER REDDY
51
POTHURAI
</body>
</html:html>

Step7: - Provide the information about the action in struts-config.xml


 <action-mappings>
<action name="NewUserAccForm" input="/nuform.jsp" path="/cua"
validate="true" scope="request" type="CUAAction">
<forward name="uacreated" path="/uac.jsp"/>
</action>
</action-mappings>
Step 8: - Provide the uac.jsp

 <% System.out.println("-- executing uac.jsp--"); %>


User account stored in db

Step 9: - Provide the information about the validations that has to be performed on
various fields in the file validation.xml

 <formset>
<form name="NewUserAccForm">
<field property="userName" depends="required">
<arg0 key="User Name" resource="false"/>
</field>
<field property="pwdOne" depends="required">
<arg0 key="Password One" resource="false"/>
</field>
<field property="pwdTwo" depends="required">
<arg0 key="Password Two" resource="false"/>
</field>
</form>
</formset>
http://localhost:8000/cncbs/nuform.jsp
----nuform.jsp----
UserName:
Password:
re-type Password:
Click
---aes--1-->3
---aes--2-->3
----nuform.jsp----

• User Name is required.


• Password One is required.
• Password Two is required.

UserName:
Password:

SUDHEER REDDY
52
POTHURAI
re-type Password:
Click
---aes--1-->0
---aes--2-->1
----nuform.jsp----

• Passwords must be same

UserName:
Password:
re-type Password:
Click
---aes--1-->0
---aes--2-->0
----CUAAction.execute----
-- executing uac.jsp--
User account stored in db
SQL> select * from users;
UNAME PONE PTWO
----------------- ------------- -----------
sudheer sunil sunil

 To take care of the validations that can not be carried out by the java script generated
by <html:javascript ----- > tag, we must provide our own java script function. In this
function code must be provided to call the java script function generated by struts & the
code to take care of additional validations.

Action Chaining: - Multiple actions can be used to process a single request. All these
actions are considered to be part of an action chain.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionOne extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----ActionOne:execute----");
// Code to perform task one
return mapping.findForward("fone");
}
}
D:\Pskr\Struts>set CLASSPATH=.;commons-beanutils.jar;servlet-api.jar;struts.jar;
D:\Pskr\Struts>javac ActionOne.java

 import javax.servlet.http.*;
import org.apache.struts.action.*;

SUDHEER REDDY
53
POTHURAI
public class ActionTwo extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----ActionTwo:execute----");
// Code to perform task Two
return mapping.findForward("ftwo");
}
}
D:\Pskr\Struts>javac ActionTwo.java

 op genarated by dispop.jsp

 <action-mappings>
<action path="/aone" type="ActionOne">
<forward name="fone" path="/atwo.do"/>
</action>
<action path="/atwo" type="ActionTwo">
<forward name="ftwo" path="/dispop.jsp"/>
</action>
</action-mappings>
http://localhost:8000/achain/aone.do
----ActionOne:execute----
----ActionTwo:execute----
op genarated by dispop.jsp

/aone.do
Action servlet

ActionOne

Browser
ActionTwo

dispop.jsp

Server
Note: - When the browser sends the request using /aone.do, the struts code executes
ActionOne, ActionTwo & then it forwards the request to dispop.jsp. in this case a single
request is processed by multiple actions (ActionOne, ActionTwo).

 What is the difference between global forward & local forward ?

SUDHEER REDDY
54
POTHURAI
A)  import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionOne extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----ActionOne:execute----");
// Code to perform task one
return mapping.findForward("fwd");
}
}
D:\Pskr\Struts>javac ActionOne.java

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionTwo extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
System.out.println("----ActionTwo:execute----");
// Code to perform task Two
return mapping.findForward("fwd");
}
}
D:\Pskr\Struts>javac ActionTwo.java

 op genarated by dispop.jsp

 <action-mappings>
<action path="/aone" type="ActionOne">
<forward name="fwd" path="/dispop.jsp"/>
</action>
<action path="/atwo" type="ActionTwo"> local forward
<forward name="fwd" path="/dispop.jsp"/>
</action>
</action-mappings>
http://localhost:8000/achain/aone.do
----ActionOne:execute----
op genarated by dispop.jsp
http://localhost:8000/achain/atwo.do
----ActionTwo:execute----
op genarated by dispop.jsp

A forward that is provided as part of the action tag is called as a local forward & it
can be used only by that action.

SUDHEER REDDY
55
POTHURAI
In the above configuration the information about the same forward is provided
twice. We can avoid this by using global forwards.

 <global-forwards>
<forward name="fwd" path="/dispop.jsp"/> global forward
</global-forwards>
<action-mappings>
<action path="/aone" type="ActionOne">
</action>
<action path="/atwo" type="ActionTwo">
</action>
</action-mappings>
http://localhost:8000/achain/aone.do
----ActionOne:execute----
op genarated by dispop.jsp
http://localhost:8000/achain/atwo.do
----ActionTwo:execute----
op genarated by dispop.jsp

A forward provided inside global-forwards tag is called as a global forward & it can be
used by any of the actions that are configured in struts-config.xml.
If the local forward & global forward is available then struts uses local forward.

 We can use try, catch blocks to deal with the exceptions. But in struts we can use
declarative exception handling mechanism to deal with the exceptions.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionOne extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
Class.forName("xxx");
System.out.println("-- class loaded --");
return mapping.findForward("fwd");
}
}
D:\Pskr\Struts>javac ActionOne.java
Note: - The code shown above throws java.lang.ClassNotFoundException.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
public class ActionTwo extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception

SUDHEER REDDY
56
POTHURAI
{
java.io.FileInputStream fis=new java.io.FileInputStream("yyy.txt");
System.out.println("-- file opend --");
return mapping.findForward("fwd");
}
}
D:\Pskr\Struts>javac ActionTwo.java
Note: - The code shown above throws java.lang.FileNotFoundException.

 cls.err=Class is not available


file.err=File is not available

 <% System.out.println("-- executing ehone.jsp --"); %>


<%@ taglib uri="/tags/struts-html" prefix="html" %>
<html:errors />
output of ehone.jsp

 <% System.out.println("-- executing ehtwo.jsp --"); %>


<%@ taglib uri="/tags/struts-html" prefix="html" %>
<html:errors />
output of ehtwo.jsp

 op genarated by dispop.jsp

We can provide the information about what must be done by struts when an exception
is thrown as shown below.
 <global-exceptions>
<exception key="file.err" type="java.io.FileNotFoundException"
path="/ehone.jsp"/>
<exception key="cls.err" type="java.lang.ClassNotFoundException"
path="/ehtwo.jsp"/>
</global-exceptions>
<global-forwards>
<forward name="fwd" path="/dispop.jsp"/>
</global-forwards>
<action-mappings>
<action path="/aone" type="ActionOne">
</action>
<action path="/atwo" type="ActionTwo">
</action>
</action-mappings>
http://localhost:8000/cferr/aone.do
-- executing ehtwo.jsp --
• Class is not available
output of ehtwo.jsp
http://localhost:8000/cferr/atwo.do
-- executing ehone.jsp --

SUDHEER REDDY
57
POTHURAI
• File is not available

output of ehone.jsp
When java.io.FileNotFoundException is thrown, struts add an error with the key file.err
& it forwards the request to ehone.jsp.

 gen.err=failed due to error, contact admin

 <global-exceptions>
<exception key="gen.err" type="java.lang.Exception" path="/ehone.jsp"/>
</global-exceptions>
http://localhost:8000/cferr/aone.do
-- executing ehone.jsp --

• failed due to error, contact admin

output of ehone.jsp
http://localhost:8000/cferr/atwo.do
-- executing ehone.jsp --

• failed due to error, contact admin

output of ehone.jsp

 When java.lang.ClassNotFoundException is thrown struts will try to find the


information about ClassNotFoundException in the exception tags. In the above
configuration this information is not available. In this case struts uses the information
about java.lang.Exception as it is the super class of ClassNotFoundException .
As part of struts a set of standard actions like
org.apache.struts.actions.ForwardAction,
org.apache.struts.actions.IncludeAction,
org.apache.struts.actions.SwitchAction,
org.apache.struts.actions.DispatchAction etc are provided.

 public class OAAction extends Action {


// code for opening account (5 lines)
}
public class CAAction extends Action {
// code for closing account (3 lines)
}
public class GADAction extends Action {
// code for getting account info (4 lines)
}
public class UAAction extends Action {
// code for updating account (5 lines)
}

SUDHEER REDDY
58
POTHURAI
 The above four classes performs related actions and we have very less amount of code
in these classes. Instead of providing multiple classes like this, we can provide a single
class to perform related actions using DispatchAction.
 import javax.servlet.http.*;
import org.apache.struts.actions.*;
import org.apache.struts.action.*;
public class MultiAction extends DispatchAction
{
public ActionForward openAcc(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
// Code to open an account
return mapping.findForward("ao");
}
public ActionForward closeAcc(ActionMapping mapping,ActionForm
form,HttpServletRequest request,HttpServletResponse response) throws Exception
{
// Code to closing an account
return mapping.findForward("ac");
}
}
D:\Pskr\Struts>javac MultiAction.java
To take of the actions we must provide multiple methods like openAcc, closeAcc.
The parameter types & the return type of these methods must be same as that of execute
method.

 Output generated by ao.jsp


 Output generated by ac.jsp

As part of struts-config.xml we must provide the configuration of the action as


shown below.
 <action-mappings>
<action path="/ma" type="MultiAction" parameter="mname">
<forward name="ao" path="/ao.jsp"/>
<forward name="ac" path="/ac.jsp"/>
</action>
</action-mappings>

The method openAcc will be executed when the client sends the request using the URL
shown below
http://localhost:8000/mact/ma.do?mname=openAcc
Output generated by ao.jsp

The method closeAcc will be executed when the client sends the request using the URL
shown below
http://localhost:8000/mact/ma.do?mname=closeAcc
Output generated by ac.jsp

SUDHEER REDDY
59
POTHURAI

The execute method available in DispatchAction class takes care of calling the
methods like openAcc, closeAcc.
 In case of a big project there will be more number of beans & Action classes. If we
provide the information about to many numbers of form beans & Actions in a single file,
the configuration file will become unmanageable.
To avoid the problems started about we can use multiple configurations files. For
this we must divide the project in to multiple modules & use one configuration file every
module.
Module name Config file name
1) struts-config.xml
2) modone sc-xxx.xml
3) modtwo sc-yyy.xml

Module without name


 We must provide the information about the names of the modules & the configuration
files in web.xml.

 <web-app>
<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/modone</param-name>
<param-value>/WEB-INF/sc-xxx.xml</param-value>
</init-param>
<init-param>
<param-name>config/modtwo</param-name>
<param-value>/WEB-INF/sc-yyy.xml</param-value>
</init-param>
</servlet>
--------
--------
</web-inf>

 In the WEB-ROOT directory we must create the directories with the names modone,
modtwo. We must place the Resources (html files, JSP) of modone module in modone
directory.

 <% System.out.println("-- urform.jsp --"); %>


Output generated by urform.jsp

SUDHEER REDDY
60
POTHURAI
The information about the form beans, Actions of modone must be provided in sc-
xxx.xml.
If we use the URL http://localhost:8000/bproj/modone/urform.jsp for generating
the form that is part of modone. It will fail as struts will work with the module without
name (default module) by default.

To solve this problem we must configure switch action in struts-config.xml as


shown below.
 <action-mappings>
<action path="/sm" type="org.apache.struts.actions.SwitchAction"/>
</action-mappings>

SwitchAction takes the responsibility of switching from one module to another


module. SwitchAction uses two parameters (prefix, page). For accessing urform.jsp
available in modone, we can use the following URL
http://localhost:8000/bproj/sm.do?prefix=/modone&page=/urform.jsp
-- urform.jsp --
Output generated by urform.jsp

 <% System.out.println("-- one.jsp --"); %>


output generated by one.jsp

 <% System.out.println("-- two.jsp --"); %>


output generated by two.jsp
http://localhost:8000/bproj/one.jsp
-- one.jsp --
output generated by one.jsp
http://localhost:8000/bproj/two.jsp
-- two.jsp --
output generated by two.jsp

(*.do) /one.jsp
action

/two.jsp

one.jsp Client

two,jsp

Server

SUDHEER REDDY
61
POTHURAI
When the browser sends the request for one.jsp, the container executes one.jsp
directly. In this case the struts code available in action servlet will not be executed. Some
of the tags that are part of struts tag libraries may not work in this case.
 We can configure the ForwardAction as shown below
<action-mappings>
<action path="/xxx" parameter="/one.jsp"
type="org.apache.struts.actions.ForwardAction"/>
<action path="/yyy" parameter="/two.jsp"
type="org.apache.struts.actions.ForwardAction"/>
</action-mappings>
http://localhost:8000/bproj/xxx.do
-- one.jsp --
output generated by one.jsp
http://localhost:8000/bproj/yyy.do
-- two.jsp --
output generated by two.jsp

(*.do) /one.jsp
action

/two.jsp

Client
ForwardAction

one.jsp two,jsp

Server
When the browser sends the request using /xxx.do the following tasks will be carried
out in the web container: -
1) Web container starts the execution of Action Servlet.
2) Action Servlet will start executing the ForwardAction
3) ForwardAction uses the value of parameter (/one.jsp).
4) The request will be forwarded to one.jsp.

 In this case before executing one.jsp web container executes struts code available in
struts-config.xml.

 SQL> create table accounts(aid number(3), cname varchar(10), balance


number(10,2));
Table created.

SQL> insert into accounts values(1,'cone',10000);


1 row created.

SUDHEER REDDY
62
POTHURAI
SQL> insert into accounts values(2,'ctwo',20000);
1 row created.

SQL> select * from accounts;


AID CNAME BALANCE
-------------- --------------- --------------
1 cone 10000
2 ctwo 20000
MVC design pattern
Note: - Struts framework is based on MVC architecture. Action Servlet
Action
Form Bean

1 (Controller)
B Servlet
R Request
O 2
W 3 Instantiate
S
E
R
5 (View)
Response JSP
4
(Model)
Browser Java Bean EIS
Servlet Container

Account One: accone


Account Two: acctwo
Amount: amount

Form Name: - FTForm


Validations: - All the fields are required.

In the carrier application, we are provided the business logic as part of the Action
classes. This approach is not recommends, that we must use the model classes for the
implementation of the business logic.

 import java.sql.*;
public class FTManager
{

SUDHEER REDDY
63
POTHURAI
public void transferFunds(int accone, int acctwo, float amount)throws Exception
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger");
String vsql1="select balance from accounts where aid="+accone;
Statement stmt=con.createStatement( );
ResultSet rs=stmt.executeQuery(vsql1);
rs.next( );
float bal=rs.getFloat("balance");
if(bal<amount)
{
throw new Exception("Funds not available");
}
String vsql2="update accounts set balance=balance-"+amount+" where
aid="+accone;
String vsql3="update accounts set balance=balance+"+amount+" where
aid="+acctwo;
stmt.executeUpdate(vsql2);
stmt.executeUpdate(vsql3);
// code to send SMS to the customer
}
}
D:\Pskr\Struts>set CLASSPATH=.;ojdbc14.jar
D:\Pskr\Struts>javac FTManager.java

Note: - In the above model class we have not use anything related to Servlet API, Struts
API. This class is not dependent upon struts, servlet API & this class will work without
these API’s

 import java.awt.*;
import java.awt.event.*;
public class GuiApp extends Frame implements ActionListener
{
private TextField tfaccone;
private TextField tfacctwo;
private TextField tfamount;
private Button btransfer;
public GuiApp( )
{
tfaccone=new TextField("Acc No One Here");
tfacctwo=new TextField("Acc No two Here");
tfamount=new TextField("Amount Here");
btransfer=new Button("Transfer");
btransfer.addActionListener(this);
setLayout(new FlowLayout( ));
add(tfaccone);

SUDHEER REDDY
64
POTHURAI
add(tfacctwo);
add(tfamount);
add(btransfer);
}
public void actionPerformed(ActionEvent ae)
{
try
{
String vaccone=tfaccone.getText( );
String vacctwo=tfacctwo.getText( );
String vamount=tfamount.getText( );
FTManager ftm=new FTManager( );
ftm.transferFunds(Integer.parseInt(vaccone),Integer.parseInt(vacctwo),
Float.parseFloat(vamount));
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void main(String a[ ]) throws Exception
{
GuiApp win=new GuiApp( );
win.pack( );
win.show( );
}
}
D:\Pskr\Struts>javac GuiApp.java
D:\Pskr\Struts>java GuiApp

java.lang.Exception: Funds not available

SQL> select * from accounts;


AID CNAME BALANCE

SUDHEER REDDY
65
POTHURAI
------------- ------------- ---------------
1 cone 7500
2 ctwo 22500
The above model class FTManager can be used as part of a GUI application, a web
application developed using struts, a web application developed without using struts,
applets etc….

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.validator.*;
public class FTInfoFB extends DynaValidatorForm
{
public void reset(ActionMapping mapping,HttpServletRequest request)
{
System.out.println("----reset----");
set("accone","0");
set("acctwo","0");
set("amount","0.0");
}
}
D:\Pskr\Struts>set CLASSPATH=.;struts.jar;servlet-api.jar;ojdbc14.jar;commons-
beanutils.jar
D:\Pskr\Struts>javac FTInfoFB.java
Note: - The form bean classes depends upon the struts API & servlet API.

 import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
public class FTAction extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response)throws Exception
{
System.out.println("----FTAction.execute----");
FTInfoFB fb=(FTInfoFB)form;
String vaccone=(String)fb.get("accone");
String vacctwo=(String)fb.get("acctwo");
String vamount=(String)fb.get("amount");
FTManager ftm=new FTManager( );
ftm.transferFunds(Integer.parseInt(vaccone),Integer.parseInt(vacctwo),
Float.parseFloat(vamount));
return mapping.findForward("ftsuc");
}
}
D:\Pskr\Struts>javac FTAction.java
Note: - The above Action class depends upon the struts API & servlet API.

SUDHEER REDDY
66
POTHURAI
 Can we provide business logic as part of the form bean classes & action classes?
A) Its not recommended providing the business logic in the action class & in the form
bean class. We can use these classes only as part of the struts based applications.
If the business logic is implemented in a separate set of classes called as model
classes then we can use the model classes as part of different kinds of applications like web
applications, GUI applications etc….

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


<% System.out.println("----ftform.jsp----"); %>
<html:html locale="true">
<head> <title> Transfer amount </title> </head>
<body>
<html:errors />
<html:form action="/ftAction.do">
<b>Account One :</b>
<html:text property="accone"/> <br>
<b>Account Two :</b>
<html:text property="acctwo"/> <br>
<b>Amount :</b>
<html:text property="amount"/> <br>
<html:submit property="submit" value="Transferr"/> <br>
</html:form>
</body>
</html:html>

 <% System.out.println("----fts.jsp----"); %>


Amount transfer successfully

 <form-beans>
<form-bean name="FTForm" type="FTInfoFB">
<form-property name="accone" type="java.lang.String"/>
<form-property name="acctwo" type="java.lang.String"/>
<form-property name="amount" type="java.lang.String"/>
</form-bean>
</form-beans>
<action-mappings>
<action name="FTForm" type="FTAction" input="/ftform.jsp"
path="/ftAction" validate="true" scope="request">
<forward name="ftsuc" path="/fts.jsp"/>
</action>
</action-mappings>

 <formset>
<form name="FTform">
<field property="accone" depends="required">
<arg0 key="Account One" resource="false"/>
</field>

SUDHEER REDDY
67
POTHURAI
<field property="acctwo" depends="required">
<arg0 key="Account Two" resource="false"/>
</field>
<field property="amount" depends="required">
<arg0 key="Amount" resource="false"/>
</field>
</form>
</formset>
http://localhost:8000/ftapp/ftform.jsp
----ftform.jsp----
----reset----
Account One :
Account Two :
Amount :
Click
----reset----
----FTAction.execute----
----fts.jsp----
Amount transfer successfully
SQL> select * from accounts;
AID CNAME BALANCE
--------------- ------------ -----------------
1 cone 4500
2 ctwo 25500

 1) Struts is based on MVC architecture. In the above application ftform.jsp & fts.jsp
acts as a View Component.
2) FTManager contains the business logic and it acts as the Model Component.
3) The code in Action servlet, form bean, Action is responsible for deciding about how the
application as to react when the user interacts with the application. These 3 are
considered to be part of Controller Component.

DAO design pattern: - (data Access object).


1) For accessing the data available in the database, we can use the API’s like JDBC, Top
Link, JDO (Java Data Objects), JPA (Java Persistence API) erc….
2) Companies will constantly change the API/technology for accessing the data in the
databases.
Ex: - A project developed by a company using JDBC API in 2004, may change the
data access code using Hibernate API in 2008.
 If we provide the code to access the data base + the code that need not access the
database together as part of the model classes for the implementation of business logic
then modifying the data access logic using another API will be difficult.
To solve this problem we can use DAO design pattern.
 SQL> select * from accounts;
AID CNAME BALANCE
--------------- ------------ -----------------
1 cone 8000

SUDHEER REDDY
68
POTHURAI
2 ctwo 22000
 public class Account
{
private long aid;
private String cname;
private float balance;
// setters & getters supporting aid, cname, balance properties.
}

/* Account a=new Account( );


// get the data from Accounts table & put the data in Account object
a.setAid(10);
a.setCname(“chun”);
a.setBalance(13000);
AccountsDAO adao=new AccountsDAO( ); */

We can use an Account object to represent the data of 1 row available in accounts
table.

 DAO class contains the code to access the data available in the database.

Ex: - /* class developed in 2004 */


public AccountsDAO
{
public void save(Account acc)
{
// jdbc code to store a record in accounts table.
}
public Account getAccount(long id)
{
/* jdbc code to get a record from accounts table & load the data in Account
object */
return acc;
}
public Vector getAccounts( )
{
// jdbc code to get the records from accounts table
}
public void delete(Account a)
{
// jdbc code to remove record from accounts table
}
public void update(Account a)
{
// jdbc code to modify the record in accounts table.
}
}

SUDHEER REDDY
69
POTHURAI
Like AccountsDAO several DAO classes will be provided in the project. We can
implement FTManager without using data access code directly as shown below.
 /* class developed in 2004 */
public class FTManager
{
public void transferFunds(int accone, int acctwo, float amount) throws Exception
{
AccountsDAO adao=new AccountsDAO( );
Account a1=adao.getAccount(accone);
Account a2=adao.getAccount(acctwo);
if(a1.getBalance( )<amount)
{
// throw Eception
}
a1.setBalance(a1.getBalance( )-amount);
a2.setBalance(a2.getBalance( )+amount);
adao.update(a1);
adao.update(a2);
// code to send SMS to the customer
}
}
In the above class there in no JDBC code.

Model Classes

(Business logic)

DAO Classes

(Data access logic)

Data Base
If we need to use Hibernate in place of jdbc then we need not change the model
classes. In this case we need to modify the data access code available in DAO classes.
Switching from one data access technology to another data access
technology will be easy if we use DAO design pattern.

TilesPlugin: - TilesPlugin simplifies the development of a web application with consistent


views (similar look for all the pages viewed by the user of the application).
TilesPlugin uses the definitions available in tiles-defs.xml.
In order to use the Tiles plug-In, we must first decide about the layout of the page.

SUDHEER REDDY
70
POTHURAI

CLogo Menu Options (links) TopTile

Context according to the Menu Option MiddleTile


Chosen by the user

Copyright Notice. BottomTile

Layout One

CLogo Menu Options (links)


TopTile

Context according to
Right
Sub Menu the Menu Option
Left MiddleTile
Options Chosen by the user
Middle
Tile

Copyright Notice BottomTile

Layout Two
Once the Layout is decided, a jsp must be provided according to the Layout using the
tags that are part of struts-tiles tag libraries.
 <%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<html>
<head>
<title> <tiles:getAsString name="title"/> </title>
</head>
<body bgcolor="#cccc99">
<table>
<tr>
<td> <tiles:insert attribute="TopTile"/> </td>
</tr>
<tr>
<td> <tiles:insert attribute="MiddleTile"/> </td>
</tr>
<tr>
<td> <tiles:insert attribute="BottomTile"/> </td>
</tr>
</table>
</body>
</html>

SUDHEER REDDY
71
POTHURAI
In the above JSP title, TopTile, MiddleTile & BottomTile are called as the Components.
Once the Layout is created, the same layout can be used for generating all the
views.
 <%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<tiles:insert page="layout.jsp">
<tiles:put name="title" value="products"/>
<tiles:put name="TopTile" value="header.jsp"/>
<tiles:put name="MiddleTile" value=" productsbody.jsp "/>
<tiles:put name="BottomTile" value=" footer.jsp "/>
</tiles:insert>

Definitions improve the flexibility of the application.


 <tiles-definitions>
<definition name="ourdef" path="/layout.jsp">
<put name="title" value="products"/>
<put name="TopTile" value="/header.jsp"/>
<put name="MiddleTile" value="/productsbody.jsp"/>
<put name="BottomTile" value="/footer.jsp"/>
</definition>
</tiles-definitions>

products.jsp can be re-written using the definition as shown below


 <%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<tiles:insert definition="ourdef">
</tiles:insert>

SUDHEER REDDY
72
POTHURAI
 <%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<tiles:insert definition="ourdef">
<tiles:put name="title" value="services"/>
<tiles:put name="MiddleTile" value="servicesbody.jsp"/>
</tiles:insert>

Note: - The values of title, MiddleTile provide using the put tags in the above JSP
overrides the values provide in the definition (tiles-def.xml).

SUDHEER REDDY

You might also like