Professional Documents
Culture Documents
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>
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
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
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
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)
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)
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>
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.
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>
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 ok button
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
<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.
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.
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
<%
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
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.
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
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
--------
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.
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
•
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
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
SUDHEER REDDY
22
POTHURAI
<forward name="disperrs" path="/mde.jsp"/>
</action>
</action-mappings>
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.
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
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.
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
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>
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
Prod Id :
Prod Name :
Price :
Click
----setProdId---->
----setProdName---->abc
----setProdPrice---->
---Size--1-->0
---Size--2-->2
----npform.jsp----
----getProdId---->
----getProdName---->abc
----getProdPrice---->
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.
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.
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.
true
ActionForm
reset
validate
…….
extends
DynaActionForm
set (..)
get(.)
extends
SUDHEER REDDY
32
POTHURAI
OurOwnFB
We need to provide getters & setters
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
<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>
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
<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>
User Name :
Password :
Age :
Email :
Click
----reset----
----validate----
----urform.jsp----
User Name :
Password :
Age :
Email :
Click
----reset----
----validate----
----urform.jsp----
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.
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
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
<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>
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
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 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
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.
SUDHEER REDDY
42
POTHURAI
</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:
Student Name:
Age:
Click
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.
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>
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
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.
<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>
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
SUDHEER REDDY
51
POTHURAI
</body>
</html:html>
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----
UserName:
Password:
SUDHEER REDDY
52
POTHURAI
re-type Password:
Click
---aes--1-->0
---aes--2-->1
----nuform.jsp----
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).
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.
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.
<global-exceptions>
<exception key="gen.err" type="java.lang.Exception" path="/ehone.jsp"/>
</global-exceptions>
http://localhost:8000/cferr/aone.do
-- executing ehone.jsp --
output of ehone.jsp
http://localhost:8000/cferr/atwo.do
-- executing ehone.jsp --
output of ehone.jsp
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.
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
<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.
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.
(*.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.
SUDHEER REDDY
62
POTHURAI
SQL> insert into accounts values(2,'ctwo',20000);
1 row created.
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
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
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….
<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.
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.
}
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.
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 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.
SUDHEER REDDY
70
POTHURAI
Layout One
Context according to
Right
Sub Menu the Menu Option
Left MiddleTile
Options Chosen by the user
Middle
Tile
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>
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