Struts Validator Framework - lab oriented lesson

We will now have a brief and practical recapitulation of a typical Struts-based application and then proceed to illustrate the use of Validator framework, with a lab-oriented lesson.

Struts Validator Framework - lab oriented lesson

STRUTS-VALIDATOR FRAMEWORK

R.S.Ramaswamy

( developeriq..Oct-2005)

     

Struts & validation

Validation is an essential feature in any web-application and to make it easier, the Validation Framework has been bundled with Struts1.1 version. In this hands-on tutorial , the author explains how we can use this readymade framework.In this first part, a simple struts demo with non-framework based validation , is developed.

We had seen an introduction to Struts in Jan-2005 issue of DeveloperIQ. We will now have a brief and practical recapitulation of a typical Struts-based application and then proceed to illustrate the use of Validator framework, with a lab-oriented lesson.

Since its introduction in 2001, Struts has been widely adopted and despite the emergence of more 'official' JSF

last year (2004), Struts is still holding its ground and only recently, companies seem to be exploring JSF.As a large number of applications have already been built using Struts, it may be that only a combination of Struts and JSF, rather than pure JSF, will be adopted by developers and software houses, right now.It may take some time before JSF completely replaces Struts.

Java webserver technology has progressed through Servlets, plain JSP, JSP using beans, Tag-library, MVC, JSTL,STRUTS and JSF. As Struts involves every one of the preceding technologies, a good knowledge of Struts is equivalent to competence in J2EE Web-Tier.Thus, Struts is still very important for developers and students.

Most learners find getting started with Struts , very difficult and confusing, partly because of the books and articles in circulation. The exception is the tutorial by Marty Hall ( 'www.coreservlets.com' & 'www.moreservlets.com'), because, rather than beginning with a lengthy theoretical treatment of Struts, it gives more importance to hands-on procedure.Another book is 'Mastering Jakarta Struts' by James Goodwill with some modifications. We will adopt the same method .

 HOW TO INSTAL STRUTS?

Unzip Jakarta-Struts1.1 into C:\unzipped.
We get a folder by the same name.When we expand the folder, we find a folder named 'webapps'. Expand this folder and we find a number of '*.war' files ( web-archive files).One such file is 'struts-blank.war'.
We copy struts-blank.war and paste it in
'e:\tomcat41\webapps' folder.
We are using d:\JDK1.4.2 and
we cd to e:\tomcat41\bin
and
set JAVA_HOME=D:\JDK1.4.2 and then startup

This will automatically expand the war file to create a folder in e:\tomcat41\webapps named as 'struts-blank'.

To shutdown the Tomcat server, we give the command,

e:\tomcat41\bin>shutdown.

After shutting down the tomcat server, we rename the struts-blank folder as (say) modelapp.If we open modelapp folder, we will find the standard j2ee directory structure and all the necessary framework files in-place.This is the quickest and best method to develop a struts-based application.

We can cd to e:\tomcat41\webapps\modelapp\WEB-INF\classes folder.We will find a 'resources' folder already there.We should create a subfolder under 'classes' folder and name it as 'modelpack' (for package).

With these preliminaries over, we can turn our attention to the files in our modelapp.
Any typical struts-based application, will have the following six files .
1) modelSubmit.jsp
2) modelForm.java
3) modelHelper.java
4) modelResult.java
5) modelAction.java
6) modelOutput.jsp

Our project folder is g:\mydir.

cd to g:\mydir and md modelpack. (this is the package name ).

cd to modelpack.

 We create all the above six files in this folder.

We have to set path & classpath for this command window as follows:

>set path=c:\windows\command;
d:\jdk1.4.2\bin
>set classpath=g:\mydir;
c:\quick\struts.jar;

e:\tomcat41\common\lib\servlet.jar

( we have copied struts.jar from modelapp\WEB-INF\lib folder into c:\quick for ease.)  modelSubmit.jsp is the opening page invoked by the user. When he submits this page ,the ActionServlet(controller) is invoked. It looks into the struts-config.xml file where action-mapping has been mentioned by us. This mapping specifies that if the path began with '/model', the controller should collect the data from modelSubmit.jsp, populate the modelForm bean with these data and then pass the bean to modelAction class. It also says that if any validation logic succeeds, the forward path should be to modelOutput.jsp("success") and otherwise, it should be modelSubmit.jsp ("failure").

 The modelAction class collects the data from modelForm instance and invokes the modelHelper to carry out the business-logic.

The helper carries out the job and returns the value to the modelAction. The modelAction then creates an instance of modelResult ( a value bean) and sets its value. It then creates a session context and passes this bean as its 'result' attribute. Finally, the modelOutput.jsp collects this result and displays it without using any scriptlet. Therefore, the ActionServlet simply controls the flow depending on the settings entered by us in the struts-config.xml file .The Action class does not do anything except invoking the helper and setting the value for result bean. The business logic , is preferably executed by a helper class ( a function bean).So, we have effectively implemented MVC pattern where M,(model..helper)

 V(view ..the jsp) and

C(controller..Action servlet) do their respective jobs. The entire thing allows Declarative change management through the struts-config.xml file. For smooth work, it is advisable not to tamper with the web.xml file. We will now create the required files, as follows, in the correct order. 0

We are now in g:\mydir\modelpack folder.

set path=c:\windows\command;

d:\jdk1.4.2\bin 1

set classpath=g:\mydir;

c:\quick\struts.jar;

e:\tomcat41\common\lib\servlet.jar 2

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

We are using Struts-specific tag library. The Tag-library-descriptor files (tld) are already in place in our WEB-INF folder. So, no special steps are necessary.

 If we had been following the earlier tutorial on Struts, we need give particular attention to <html:errors /> tag now. 3

This is for displaying any error messages.

There are two fields, namely, 'name' and 'code'.

---------------------------------- 4

// g:\mydir\modelpack\modelSubmit.jsp

<%@ taglib prefix="html" uri="/WEB-INF/struts-html.tld" %>
<%@ taglib prefix="bean" uri="/WEB-INF/struts-bean.tld" %>
<%@ taglib prefix="logic" uri="/WEB-INF/struts-logic.tld" %>
<html:html>
<body bgcolor=pink>
 <html:errors />
<html:form action="/model"
name="modelForm"
type="modelpack.modelForm">
<html:text property="name"/> <br>
<html:text property="code"/> <br>
<html:submit/>
</html:form>
</body>
</html:html>

=========================================== 5

After creating this input file, we have to create a javabean, in our case, named as 'modelForm.java'. This is an attribute bean and sometimes known as formbean.Following the standard javabean naming convention, we provide setter and getter methods for all the fields in the modelSubmit.jsp.

However, this is not just the usual javabean , but Struts-specific bean.For this reason, we have to derive it from Strut's ActionForm  class.( Shortly , when we use the validator framework, we will be deriving our modelForm not from ActionForm but from ValidatorForm. This may be kept in mind). In order to derive it from Struts ActionForm, we have to import

'org.apache.struts.action.*'. Moreover, 6

all the Struts classes are based on Servlet API and we need to import

'javax.servlet.http.*' also.

Special attention can be given to the validate method.( when we base our modelForm on ValidatorForm, we won't be providing this method).We have written some rudimentary validation check to see if the field is empty and if so an error instance is created with the 'key' (errors.nullname). 7

Similarly (errors.nullcode). There is a file known as 'Application.properties' in 'WEB-INF\classes\resources' and at the end of that file we will add the following lines.

=====================================

errors.nullname=<li> ENTER YOUR NAME</li> 8

errors.nullcode=<li>ENTER YOUR CODE</li>

errors.nomatch=<li>DOES NOT MATCH</li>

Therefore, we will get the specified error messages. 9

*******************************************

//g:\mydir\modelpack\modelForm.java

package      modelpack;   
import javax.servlet.http.*; 
import org.apache.struts.action.*; 
public class modelForm extends ActionForm 
{ 
     String   name  =  null; 
     String   code  =  null;    
  public String getName() 
  { 
    return   name; 
  }  
  public void setName(String  s) 
  { 
     name=s; 
  } 
   //------------------------------- 
  public String getCode() 
  { 
     return   code; 
  }  
  public void setCode(String  s) 
  { 
     code=s; 
  }   
  public   void    reset (ActionMapping     mapping, HttpServletRequest     request) 
  { 
      name   =   null; 
      code   =   null; 
  } 
   public  ActionErrors    validate (ActionMapping    mapping, HttpServletRequest     request) 
       { 
ActionErrors   errors  = new ActionErrors();   
           if( name.length()==0) 
           { 
            errors.add("name", new ActionError("errors.nullname")); 
           } 
           if(code.length()==0) 
           { 
           errors.add("code", new ActionError("errors.nullcode")); 
           } 
       return   errors; 
       }    
}

=========================================== 0

 The modelAction class is derived from Action class of Struts. This is not to be confused with the ActionServlet  class of the Struts framework. The ActionServlet is the controller and works in the background.

It simply collects data from modelSubmit.jsp , populates the modelForm with those values and then sends the form to the modelAction. Sometimes, in simple demo applications, the action class itself may carry out the business logic and directly send the result to the output.jsp.

But, the preferred method is to use a function bean ( a helper class) such as modelHelper. This enables 'de-coupling' of various stages. 1

The modelAction class collects the data from the modelform bean. Just for a very simple illustration, we compare the name and code and if they match, the helper class bean is asked to 'inform' and the resulting string returned by this helper bean is set as value for the valuebean instance 'tom'. The 'tom' bean is set as the session-attribute "result".With this note, we can easily understand the code, given below.

 As the 'modelAction' class makes use of 'modelHelper' and 'modelResult' beans, they are given ahead of modelAction class.

------------------------------------- 2

// g:\mydir\modelpack\modelHelper.java

package   modelpack; 
public class modelHelper 
 { 
    public   String inform() 
    { 
        return "Correct   Code!...."; 
    } 
}

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

// g:\mydir\modelpack\modelResult.java 3

package   modelpack; 
public class modelResult 
{ 
  String    value; 
  
   public  modelResult() 
   { 
   value = " "; 
   } 
   public String   getValue() 
   { 
   return   value; 
   } 
   public void  setValue(String   v) 
   { 
   value   =   v; 
   } 
}

*******************************************

// g:\mydir\modelpack\modelAction.java

package  modelpack; 
import java.io.*; 
import java.util.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
import org.apache.struts.action.*; 
public class modelAction extends Action 
{ 
  public ActionForward   execute 
            (ActionMapping       mapping, 
               ActionForm          form,  
          HttpServletRequest    request, 
          HttpServletResponse   response) 
   throws IOException, ServletException 
  {                                  
 modelForm  modelform = (modelForm) form; 
  String       a = modelform.getName(); 
  String       b = modelform.getCode(); 
  
  if(a.equals(b)) 
  { 
 modelHelper helper = new modelHelper(); 
 String    r       = helper.inform(); 
  
modelResult  tom  = new modelResult(); 
 tom.setValue(r); 
  
 HttpSession session = request.getSession(); 
 session.setAttribute("result", tom); 
 return(mapping.findForward("success")); 
  } 
  else 
    { 
 ActionErrors errors = new ActionErrors(); 
  errors.add (ActionErrors.GLOBAL_ERROR, new ActionError("errors.nomatch")); 
  saveErrors(request,errors); 
   return(mapping.findForward("failure"));     
    }     
 } 
}

======================================= 4

Finally, we takeup the modelOutput.jsp. which simply collects the data from the bean and display it.

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

// g:\mydir\modelpack\modelOutput.jsp 5

*******************************************  
( We can also write the modelOutput.jsp as given below. In this method, we are using Struts-specific tags , whereas in the previous method, we used JSP tags only).

--------------------------------------
// g:\\mydir\modelpack\modelOutput.jsp
// ( second version)  
<%@ taglib prefix="html"
uri="/WEB-INF/struts-html.tld" %>
 
<%@ taglib prefix="bean"
uri="/WEB-INF/struts-bean.tld" %>
 
<%@ taglib prefix="logic"
uri="/WEB-INF/struts-logic.tld" %>
 
<html:html>
<body bgcolor=yellow>
<bean:write name="result" property="value"  />
</body>
</html:html>
======================================

After creating all the above files, compile the four java classes 6

>javac *.java

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

If we had followed the steps carefully, we can compile without any difficulty. 7

Next, we copy the four class files to:

'e:\tomcat41\webapps\modelapp\WEB-INF\classes\modelpack' folder.

We copy modelSubmit.jsp and modelOutput.jsp to: 8

'e:\tomcat41\webapps\modelapp' folder.

Are we ready to test our program? NOT YET!

We have to make entries in : 9

a) struts-config.xml &
b) application.properties file.

The required entries have been given below.A

------------------------------------ 0

//e:\tomcat41\webapps\modelapp\web-inf\struts-config.xml

 
<struts-config> 
<!-- ======== Form Bean Definitions --> 
<form-beans> 
<!-- sample end sample --> 
   <form-bean 
name="modelForm" 
 type="modelpack.modelForm"/> 
 </form-beans>
<action
path = "/model"
type = "modelpack.modelAction"
name = "modelForm"
input = "/modelSubmit.jsp"
scope = ?session?
validate="true" >
<forward name="success" path="/modelOutput.jsp"/>
<forward name="failure" path="/modelSubmit.jsp"/>
 </action>
</action-mappings> /WEB-INF/validator-rules.xml, /WEB-INF/validation.xml"/>

<!-- ================================ Message Resources Definitions -->

****************************************** 1

// e:\tomcat41\webapps\modelapp\web-inf\classes\resources\

application.properties

# -- standard errors -- 
# -- validator -- 
errors.invalid={0} is invalid. 
errors.maxlength={0} can not be greater than {1} characters.

# -- myerror-messages -- 2

errors.nullname=<li> ENTER YOUR NAME</li>
errors.nullcode=<li>ENTER YOUR CODE</li>
errors.nomatch=<li>DOES NOT MATCH</li>

*******************************************

We are now ready to test our application. First, start the tomcat4 server 3

e:\tomcat41\bin>SET JAVA_HOME=D:\JDK1.4.2

e:\tomcat41\bin>startup

This will start the tomcat server. Now, we type the Url as : 4

'http://localhost:8080/modelapp/modelSubmit.jsp'

We will get the entry form with two fields. If we click the submit button, without entering name or code, we are taken back to modelSubmit.jsp with the message

'ENTER YOUR NAME' /'ENTER YOUR CODE'. 5

If we enter SAM for name and TOM for code,

we get the error message 'DOES NOT MATCH'.but if same values are given for name and code, we get the output jsp which says that 'code is correct!'.

 Thus, we have developed a simple struts demo with validation. With this background, it is now very easy to understand the next example which makes use of Validator framework. This, we take up in part-2. 6