|
http://in.geocities.com/rsramsam/struts1.htm |
INTRODUCION TO
STRUTS FRAMEWORK
------------------
R.S.RAMASWAMY.
( published in DeveloperIQ....JANUARY-2005)
|
The Struts Framework is based on MVC (Model-View-Controller)Architecture. In the last edition, we
had seen how we can improvise our own MVC implementation without using Struts.
This helps in understanding the concepts of Struts. However, Struts offers
many advantages. For this reason, most Software Architects in |
Sound knowledge of Struts Framework
with hands-on experience in developing applications based on Struts , is
a skill that is very much in demand now. Struts Framework was developed by Craig McLanahan in 2002 and subsequently handed over
to Apache
As Sun Micro Systems, works
in close collaboration with Jakarta-Tomcat group, Struts has acquired semi-official status,
though , it is not officially endorsed by JCP, yet. Craig McLanahan
is also the architect of Tomcat4, which is the 'Reference
implementation' of Servlet & JSP API by Sun. And
the recently introduced JSF (Java Server Faces) also is the contribution
of Craig McLanahan.What is more, Craig is also the
Implementation Architect for Sun's Java Web Services Development Pack (JWSDP).
That is sufficient enough list of credentials, to indicate the backing from Sun.There
have been dissenting voices too,against Struts ,
partly because , it is somewhat difficult to learn and implement.And
even an acknowledged spokesman & member of Struts Development Team and author of Struts Tutorial , Ted Husted, had
to admit that the Struts naming of its classes leaves much to be desired. (for
instance, instead of 'ActionServlet', it could have
been called 'Controller' . Adding 'action' to everything in Struts like 'ActionForm',
'ActionServlet',Action','ActionForward' and even 'ActionErrors'
etc tends to make the beginners grumble that' there is too much
action here !' to their liking!).
And it appears that, of late,
some leading Architects feel that Struts is likely to give way to other
Open-Source technologies from the same Apache group ,like Turbine and Torque ( which are even
more obscure and less documented).Judging by the number of latest
job-advertisements calling for Struts skills, it is a bit difficult to concur
with that perception.Struts appears to have become 'de-facto' standard, like SAX, though
one wishes that everything had been done within JCP ,so that developers will
always be dealing with officially
approved standards,rather than maverick standards,
however good they might be. ( by the way, the correct term is 'struts'
and not 'structs', as is mis-spelt
often).
----------------------------------------------
-
Here are some of the
points listed by Author John Carnell
('Professional Struts Applications'-Wrox press-2003)
in favour of adopting Struts. To paraphrase....
**i)Senior
developers and Architects in large software houses are extremely over-worked
and the main job of in-house senior programmers is developing business-logic
and not application-framework!
ii) Struts framework was
built by some of the finest developers in the Industry.,and
is open-source and free.
iii)It has been tested
and debugged by hundreds of expert volunteers, thus giving it a high degree of Quality
Assurance.If
a company tries to build a similar framework by itself, it will take thousands
of expert man-hours and millions of dollars!
iv) Not adopting a well-recognized and widely accepted framework
but choosing another option, yet to gain wide community acceptance, would mean
that we are getting isolated, would find suitable coders hard to get and get diverted seriously from
the business-logic on hand and end up in managing the coders rather than
managing the code.**
----------------------------------------------
A good understanding and practical knowledge of Servlets,
JSP, JavaBeans, Tag Library, MVC Architecture ,XML config
files and Tomcat server , is required before a learner could even attempt understanding Struts.(It is for this reason,
that we covered our own MVC implementation in the last edition).
And it has to be supplemented with real practical work, to get it going. Without sufficient
lab-experience, a hundred things can go wrong!
Just a bit of careless 'casing'and package
names and we are confronted with
stubborn compile errors. Remembering the fact that xml files
also are 'case-conscious', would save us a lot of frustrating delay. And it is
so easy to get lost in the paths and classpaths of
Java, especially with 'Struts'!
Struts is a framework
for building really complex Enterprise-level
web applications.Note the emphasis on
'Enterprise-level'. Such applications are by necessity, multi-tier.
Carnell makes a neat distinction between Enterprise-services
like
Transaction management, Resource pooling, Load Balancing and
Security and Application-services like
Data-validation , error-handling, Application navigation and
screen-layout and personalization.
While EJB takes
care of Enterprise-services, the task of developing easily alterable and
maintainable Application-services in a really large web-application,
could be a maddeningly chaotic and tangled
' web'( literally) and such problems are not tackled by EJB.
Enterprise-level
projects are developed by teams and unless there is a well-known and standard
framework, the teams’ work would fail to
dovetail. The business-tier, Data-tier and presentation-tier ,all have to be
co-ordinated seamlessly. This requires that all the
teams and team-members know and practice a given standard. This point has been
forcefully stressed in web-forums. As Struts has acquired wide awareness &
acceptance, it fulfils this need admirably.
Carnell lists the
challenges of Web Development as :
i)
Stateless nature of HTTP.
ii) Limited User
Interface of HTML.
( this is addressed
effectively by WebForms in ASP.net and JSF).
iii) thousands of
concurrent users
iv) huge number of
inter-related navigation options.
Many companies have web-based applications where the number of
screens that the user can navigate to ,is in thousands!
(
SAP user-interface is composed of over 1,50,000 screens, reports and
dialog boxes!---
and they were reported
to be converting them into java-gui .to
provide platform independence.)
( p.376 of Java
Web Services by Hendricks..WROX).
For all these reasons
and more, Application-services are important and daunting to develop!
------------------
In the true spirit of MVC, the Struts framework separates the View,Controller and Model. It does not concern
itself with the implementation details of business-logic and data-access
tiers.
--------
That said, the very fact that it is an
Enterprise-level framework,presumes( or it should)
that we are using some form of EJB and some type of well-proven method of separation of Data-tier and business-logic
tier. Though, Struts has provision for local data access, it is not advisable
to use that facility for Enterprise-level work, nor does it recommend it.
At present, the recommended method is to
use a stateless EJB for data access directly or as a facade for CMP or JDO. The
advantage of CMP and JDO , is that details of the actual database product used
, do not find a place in code. This enables us to use Object Databases
too(JDO), as well as RDBMS. As Carnell rightly points out, the moment we
speak of products like Oracle/SqlServer/MySql in our code
, we get locked with vendor-specific details, which preclude changes.According to a number of authors, BMP seems to have
been less of a success, if the yardstick is 'avoidance of SQL & vendor
specific features of SQL.' and JDO is the recommended method. Oracle/PL-SQL if
used in EJB code, ties our application , inextricably with Oracle .This is undesirable.The EJB3.0 version ,to be released shortly ,is
said to favour
JDO strongly.(BMP introduces sql in java code while CMP & JDO adopt declarative
management for database and query.). ( BMP persistence code need not
necessarily be sql
but in most cases, it is sql).
Some authorities from BEA-WebLogic, are even, advocating the use of stateless-bean
for simplicity and speed.(Java Server Programming by Allama
Raju of WebLogic-WROX
press), though it may involve sql in code itself. And
a design based on such stateless-session bean can easily be exposed as XML-WebService by simple drop-in deployment in Axis.( see DeveloperIQ...April & May -2004).
Thus, unless we are careful in
implementing separation ,not merely between View , Control and Model, but going
further in separation of Model into delegation, service-location,
business logic , data access and data itself, even a Struts applications
may become brittle.(We can easily imagine, how dangerous a brittle struts
is.)In a well-designed system, each of these tiers should be pluggable (ie) any change in one tier should not affect other tiers.(ie)
The layers should be
de-coupled from each other, as much as possible.
Standard Design Patterns, such as ,
a) Business Delegate
Pattern
b) Service Locator Pattern
c) Session Facade
Pattern
are some of the patterns
recommended in the 'model' region of
Struts work!. In an earlier part of this J2EE tutorial , we had used a
simple utility bean,for carrying out a specific
function. That would be a case of 'Business Delegation'.
If such a bean is used as a client for an EJB, typically, it
would be an example of 'Service Locator'.
And if that ejb happened to be a stateless bean connecting with a CMP ,
it would illustrate 'Facade Pattern'.
Ideally, in an
( J2EE students are expected by the Industry,
to have read two famous
and essential books
on Design Patterns.]
a)" Design Patterns.: Elements of Reusable
Object-Oriented Software" by
-ERICH GAMMA &
three others
( known as GoF.'Gang of Four')
b) CORE J2EE PATTERNS
( J2EE BLUEPRINTS)
by
SUN MICROSYSTEMS
( Some Struts authors are intent in showing that the Struts
design follows some standard design patterns, while Carnell is concerned with
suggestions for implementing Design patterns in the Model stages of Struts
application. It is well to bear this in mind).
--------------------------------------------
If we are
asked to give a very brief outline of Struts, we can enumerate the following
points.
i) All requests are passed through a controller servlet, known as Action-servlet.
This is achieved by suitable 'url-mapping'
in web.xml file.We
have been doing 'URL-pattern' in
Tomcat4,when using servlets.
And in j2ee webserver
like Tomcat, this facilitates 'centralized-declarative change management', by editing the concerned XML
files, without touching the source or class files of the servlets.or
Struts Actions...
ii) All
data submitted by user are sent to corresponding ActionForm.There
are many actionforms but only one ActionServlet(because,
it is the controller).
iii) The ActionServlet, examines the source of request and extracts the data from specified actionform and sends it to a specified instance of Action
class.(as specified in struts-config.xml).
iv) The
action object carries out the business logic either directly or through helper
classes , creates an instance of valuebean, populates
this bean with data and sends the bean to the View JSP.( an instance of ActionForward).
v) The
important and distinctive feature of this arrangement is that the entire thing
is done by 'Declarative-Management'.(and hence ActionMapping)
vi)
Sometimes, the data submitted has to be validated and error messages ,
generated. (ActionErrors).
vii) We
use tags in input side and also for
output
view.(The input form also belongs to 'view' category in MVC.)( Struts-tags)
viii) The details about the ActionServlet
and other servlets if any ,in our application are
given in web.xml
ix)
Details about various action classes,forms,
action-forwards etc are given in struts-config.xml
---------------------------------------------
It is now the right time ( & 'high
time' at that!)to take up a simple and
practical example. Our focus in this tutorial is actual implementation. In an illustration,we should not introduce more than one
'unfamiliar' tool or concept. Many tutorials, bring in tools like 'Ant', 'Eclipse' etc, which have their own learning
curve! Our aim is to avoid such things and yet develop a useful lesson.
--------------------------------------------
We use the following six files, in this demo,
in that sequence too.
i) query.jsp
ii) QueryForm.java(derived from ActionForm)
iii)QueryAction.java(derived from Action)
iv) sqlbean.java ( a
utility bean)
v) resultbean.java ( a
value bean)
vi) result.jsp
( besides the web.xml & struts-config.xml files)
Where is the much-spoken-about ActionServlet?
That is provided by Struts Framework itself.
We do not subclass it, except
for advanced work.It remains unobtrusively in the
background , silently supervising things. As Ted Husted
says, many developers leave it alone. The truth is that , we need hardly set
our eyes on web.xml in this demo..or
on the sourcecode of ActionServlet.
--------------------------------------------
In our example, the
starting point is ' query.jsp', which
is invoked by the URL,
'http://localhost:8080/sam/query.jsp'.The user fills up a form
giving password and also an sql query.If
the password is 'ADMINISTRATOR', the query is executed. Otherwise, the form is presented
back to the user with the values already entered by him intact, so that he
need not fill up the form again but needs to make only the required
corrections. This is achieved by the FormBean. It is
a Struts-specific class known as 'ActionForm'.
We provide, getter and setter methods for each of the controls
in the form. In our example, these are 'password' and 'query'.We
are also using struts-tags named as 'html' tags.
(for simplicity, we are using simple text rather than password
control).Note the taglib directive. This is not JSTL
but Struts Tag Library.We should note the following
very carefully. The name of the form is given as
'queryForm' & action is 'Query'. (the case
is extremely important!).There is automatic
conversion of action from 'Query' to 'Query.do'.
============================================
// query.jsp
<%@ taglib uri="/WEB-INF/struts-html.tld"
prefix="html" %>
<html>
<body bgcolor=yellow>
This is query page <br>
<html:form action="Query"
name="queryForm"
type="demo1.QueryForm" >
Are you the Administrator?<br>
Your password
please!<br>
<html:text property="password"
/> <br>
query <br>
<html:text property="query"
size="60" /> <br>
<html:submit />
</html:form>
</body>
</html>
==============================================
Usually, in normal html
forms, the control has a 'name' attribute. But in html:text,
it is known as 'property'.
The corresponding formbean is given
below.
=========================================
All actions with extensions of '*.do', are
automatically directed to the StrutsServlet(ie) ActionServlet. In the
default web.xml file provided by the
Struts application, the actionservlet is given
'URL-pattern' as '*.do'.( see web.xml)as given below.)
-------------------------------
( We need not type even a single line of web.xml. It is already available in the Struts
application.) If the full file is printed here, it will only
look forbidding. So, the relevant portion alone is shown here.ActionServlet
configuration mentions the name of the servlet as
'action' and gives the fully qualified class-name of servlet.
This is
followed by init-parameters section.
where the 'config' param is indicated as
'struts-config.xml in
WEB-INF folder of the application.(shown in bold).This is followed
by servlet-mapping, as already mentioned.
Finally, we have tag-library descriptors for struts
custom-tag-libs
like 'html','logic', 'bean' etc.
It is worth mentioning again that we do not have to
type this file.It
is equally important that we should not corrupt this file carelessly!
It is best left alone.
-------------------------------
web.xml
===========================================
<?xml version="1.0" ....."?>
.......
.......
........
<!-- Action Servlet Configuration
-->
<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>
........
........
........
<!-- Standard
Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
.....
........
........
<!-- Struts Tag
Library Descriptors -->
<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>
....
.....
</web-app>
==============================================
.
-When the user submits the query.jsp, the formbean is automatically
filled up with the values from the jsp-page and the
flow goes to the ActionServlet.
// QueryForm.java
package demo1;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class QueryForm
extends ActionForm
{
String password =null;
String query =null;
//------------------------------
public String
getPassword()
{
return password;
}
public
void setPassword(String b)
{
password=b;
}
//-----------------------------
public
String getQuery()
{
return query;
}
public
void setQuery(String a)
{
query=a;
}
//---------------------------
public void
reset(ActionMapping mapping,
HttpServletRequest
request)
{
password=null;
query=null;
}
}
==============================================
In the struts-config.xml file,
we make two entries. One entry is for the instance of QueryForm bean and the other entry is for the instance
of QueryAction class.As the
entry for 'query action' makes a reference to 'query form', let us first see
the details of the entry for 'query form'.The struts-config.xml
file in WEB-INF folder is created by us and is the
nerve-center of customized functionality.
------------------------------------------
( this is the part dealing with the formbean)
<form-beans>
<form-bean
name="queryForm"
type="demo1.QueryForm" />
</formbeans>
------------------------------------
This means that our formbean is named
'queryForm' and is
available in demo1 subfolder of classes folder.
(WEB-INF\classes\demo1\QueryForm.class)
Carefully note the name of the bean. It is the same name given
in the instance of QueryForm
class,as it appears
in QueryAction.java,given separately.(all the
authors follow uniform pattern of naming the bean.The
class name begins with capital letter and the instance begins with
lowercase).Since all these are inter-dependent, unless we are careful, we can
never even get started with invoking the form!
-------------------------------------
The next segment of mapping in
struts-config.xml deals with
the action mapping for the instance of Action class, (ie)
QueryAction.
----------------------------
<action-mappings>
<action path="/Query"
type="demo1.QueryAction"
name="queryForm"
scope="session"
input="/query.jsp" >
<forward
name="success"
path="/result1.jsp" />
<forward name="failure"
path="/query.jsp" />
</action>
</action-mappings>
-------------------------------------
It means that the request comes from the path "/Query.do", the corresponding action class is
QueryAction class in demo1 subfolder
of classes folder of webserver.The
input is coming from query.jsp. Finally, it
says that the matching form to be used is 'queryForm'.
Therefore, the action
class extracts the properties from queryForm and does
some validation according to our code. If the user had correctly entered the
password as 'ADMINISTRATOR', processing goes on.
(the code snippet from QueryAction.java
is as given below).
---------------------------------------------
QueryForm queryForm =(QueryForm) form;
String a = queryForm.getPassword();
String b = queryForm.getQuery();
if(a.equals("ADMINISTRATOR"))
{
-------