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;
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