http://in.geocities.com/rsramsam/struts1.htm

 

 

INTRODUCION TO

STRUTS  FRAMEWORK

------------------

R.S.RAMASWAMY.

(rsramsam@yahoo.co.in)

 

         ( published in DeveloperIQ....JANUARY-2005)

                    ( www.developeriq.com)

 

   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 Enterprise level, favour the Struts Framework .In this  tutorial on Struts, I  explain its essential features , with a  simple lab-oriented practical example

 

           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 Jakarta project group.

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 Enterprise application ,based on Struts, we should provide for all the above three patterns and implement them, though , in this lesson, we are using 'business delegation' alone, to keep the example simple.

 

( 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"))

  {

 -------