Validation Using Struts

The following example uses a modified version of the EJB Struts example posted earlier.
The work directory for ant looks as follows:

<root>
mysql-ds.xml
jbosscmp-jdbc.xml
ejb-jar.xml
jboss.xml
application.xml
ApplicationResources.properties
build.xml
build.properties
build.bat
struts-config.xml
web.xml<b>
validation.xml
validator-rules.xml
web.xml
<build>
<pages>
     |authors.jsp
     |success.jsp
<src>
     |shoppingcart
          |AuthorsBean.java
          |Authors.java
          |AuthorsHome.java
          |AuthorsKey.java
          |authorsForm.java
          |authorsAction.java

Most of the files have been reused except for modifications in build.xml, authors.jsp, authorsForm.java, struts-config.xml and ApplicationResources.properties. In addition a new file validation.xml has been added.
The modifications in build.xml have been higlighted in bold:
build.xml:

<project name="Authors" default="clean" basedir=".">
	<property environment="env" />
	<property file="./build.properties" />
	<!-- the build path -->
	<path id="build.path">
		<pathelement location="${jboss.dist}/server/default/lib" />
		<pathelement location="${jboss.dist}/server/default/lib/jboss-j2ee.jar" />
		<pathelement location="${jboss.dist}/client/javax.servlet.jar" />
		<pathelement location="${build.classes.dir}" />
		<pathelement location="${struts.dir}" />
		<pathelement location="${struts.dir}/struts.jar" />
	</path>
	<target name="war" depends="compile">
		<war warfile="${war}" webxml="web.xml">
			<fileset dir="${basedir}/pages">
				<include name="*.jsp" />
			</fileset>
			<webinf dir="${struts.dir}">
				<include name="*.tld" />
			</webinf>
			<webinf dir="${basedir}">
				<include name="struts-config.xml" />
			</webinf>
			<b>
				<webinf dir="${basedir}">
					<include name="validator-rules.xml" />
				</webinf>
				<webinf dir="${basedir}">
					<include name="validation.xml" />
				</webinf>
			</b>
				<classes dir="${build.classes.dir}">
					<include name="shoppingcart/*.class" />
					<exclude name="shoppingcart/${appname}Bean.class" />
				</classes>
				<classes dir="${basedir}">
					<include name="ApplicationResources.properties" />
				</classes>
				<lib dir="${jboss.client.dir}">
					<include name="jboss-client.jar" />
					<include name="jnp-client.jar" />
				</lib>
				<lib dir="${struts.dir}">
					<b>
						<include name="*.jar" />
					</b>
				</lib>
		</war>
	</target>

	<target name="jar" depends="compile">
		<jar jarfile="${jar}">
			<fileset dir="${build.classes.dir}">
				<include name="shoppingcart/${appname}.class" />
				<include name="shoppingcart/${appname}Home.class" />
				<include name="shoppingcart/${appname}Bean.class" />
				<include name="shoppingcart/${appname}Key.class" />
			</fileset>
			<metainf dir="${basedir}" includes="jboss.xml,ejb-jar.xml,jbosscmp-jdbc.xml" />
		</jar>
	</target>

	<!-- build all, and copy to the jboss/deploy directory -->

	<target name="ear" depends="jar,war">
		<ear earfile="${ear}" appxml="application.xml">
			<fileset dir="${basedir}" includes="${jar},${war}" />
		</ear>
	</target>

	<!-- compilation options -->

	<target name="compile">
		<mkdir dir="${build.classes.dir}" />
		<javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on"
			deprecation="on" classpathref="build.path" optimize="off" />
	</target>
	<target name="build-all" depends="ear">
		<copy file="${ear}" todir="${jboss.deploy.dir}" />
		<copy file="mysql-ds.xml" todir="${jboss.deploy.dir}" />
	</target>
	<target name="clean">
		<delete file="${jar}" />
		<delete file="${ear}" />
		<delete file="${war}" />
		<delete file="${jboss.deploy.dir}/${ear}" />
		<delete file="${jboss.deploy.dir}/mysql-ds.xml" />
		<delete dir="${build.classes.dir}" />
	</target>
</project>

authorsForm.java now extends ValidatorForm instead of ActionForm:


package shoppingcart;
import javax.servlet.http.*;
public class authorsForm extends org.apache.struts.validator.ValidatorForm {
	String author;
	String isbnCode;
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getAuthor() {
		return this.author;
	}
	public void setIsbnCode(String isbnCode) {
		this.isbnCode = isbnCode;
	}
	public String getIsbnCode() {
		return this.isbnCode;
	}
};

authors.jsp has been slightly modified as shown below:

<html>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<head>
</head>
<body>
	<html:form action="/testout.matty">
		<p>
			<b><html:errors />
			</b> <br /> <bean:message key="isbnCode.label" /> <html:text
					property="isbnCode" size='10' /> <br /> <bean:message
						key="author.label" /> <html:text property="author" size='10' /> <html:submit
						value='Add' property="add" /> <html:submit value='Find'
						property="find" />
	</html:form>
</body>
</html>

While creating the war files, build.xml sees to it that all struts jars from the struts implementation go to the lib folder of the war file. It also picks up two xml files, validation.xml and validator-rules.xml from the work folder and places it under WEB-INF of the war file.

Validator-rules.xml is present in the struts implementation and can be copied over to the work folder before running build.xml. No change is to be made to validator-rules.xml and it is to be used as such.

A plug-in for validation is to be added to struts-config.
struts-config.xml has thus been modified as shown below:

struts-config.xml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
	<form-beans type="org.apache.struts.action.ActionFormBean">
		<form-bean name="authorsForm" type="shoppingcart.authorsForm" />
	</form-beans>
	<action-mappings type="org.apache.struts.action.ActionMapping">
		<action path="/testout" type="shoppingcart.authorsAction" name="authorsForm"
			scope="request"
			<b>
				validate="true" input = "/authors.jsp">
			</b>
				<forward name="successful" path="/success.jsp" />
				<forward name="failure" path="/authors.jsp" />
		</action>
	</action-mappings>
	<message-resources parameter="ApplicationResources" />
	<b><!-- Validator Configuration -->
		<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
			<set-property property="pathnames"
				value="/WEB-INF/validator-rules.xml, /WEB-INF/validation.xml" />
		</plug-in>
	</b>
</struts-config>

Here is a version of validation.xml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<form-validation>
	<formset>
		<form name="authorsForm">
			<field property="isbnCode" depends="required">
				<msg name="required" key="authorsForm.isbnCode" />
			</field>
		</form>
	</formset>
</form-validation>

For this version of validation.xml, ApplicationResources.properties is thus:

isbnCode.label=Enter Isbn Code of the book
author.label=Enter name of the author(only to create a record)
authorsForm.isbnCode=Please enter the ISBN Code

Let’s have a look at another snippet of validation.xml:

<field property="isbnCode" depends="required">
<msg name="required" key="authorsForm.isbnCode"/>
</field>

The depends attribute value and name attribute value must match for a customized message, which in this case is “required”.

Here is a non customized version of validation.xml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<form-validation>
	<formset>
		<form name="authorsForm">
			<field property="isbnCode" depends="required">
				<arg0 key="isbn.label" />
			</field>
		</form>
	</formset>
</form-validation>

For this version of validation.xml, ApplicationResources.properties looks like this:

isbnCode.label=Enter Isbn Code of the book
author.label=Enter name of the author(only to create a record)
isbn.label=ISBN code
errors.required={0} is required.


Let’s have a look at a snippet of the non-customized form of validation.xml:

<field property="isbnCode" depends="required">
<arg0 key="isbn.label"/>
</field>

In the properties file, the argument value, “isbn.label” value is used to replace {0} and “errors.required” is used in the jsp to display the error message.
There are a lot of built-in validations including email address at this link:
http://struts.apache.org/1.2.4/userGuide/dev_validator.html
Using regular expressions for validation is also a good idea.
It’s a matter of opinion whether all validations are to be done on client or on server side. Struts validations can be done using javascript on client side or on server-side as the request hits the server and comes back.
Struts can generate javascript functions. When you look at the page html you can see javascript code which was generated by Struts. JavaScript is created by struts and sent along with the html. Validation errors are caught by js before it leaves the browser hence it is client side validation. This kind of validation is rarely used.
All validation code is generated by server-side though it be javascript.
Struts also provides for pure java validations.
As earlier, let the form bean extend ValidatorForm and add to it a validate method, and add java based validations in it – that’s pure java validation and is similar to validation done in action class; the only advantage is that validation code will not clutter your action class.
validate() is called before the action class is called and returns control back to the jsp page if errors are found.

The ear file has the following structure:

authors.ear
    |<meta-INF>
         |application.xml
    |authors.jar
         |<meta-INF>
              |ejb-jar.xml
              |jboss.xml
              |jbosscmp-jdbc.xml
         |<shoppingcart>
              |AuthorsBean.class
              |Authors.class
              |AuthorsHome.class
              |AuthorsKey.class
         |authors.war
              |<web-INF>
                    |web.xml
                    |validator-rules.xml
                    |validation.xml
                    |struts-config.xml
                    |struts-tiles.tld
                    |struts-nested.tld
                    |struts-html.tld
                    |struts-logic.tld
                    |struts-bean.tld
                    |<lib>
                           |struts.jar
                           |jnp-client.jar
                           |jboss-client.jar
                           |jakarta-oro.jar
                           |commons-validator.jar
                           |commons-logging.jar
                           |commons-fileupload.jar
                           |commons-digester.jar
                           |commons-beanutils.jar
                           |antlr.jar
                    |<classes>
                           |ApplicationResources.properties
                           |<shoppingcart>
                    |Authors.class
                    |AuthorsHome.class
                    |AuthorsKey.class
                    |authorsAction.class
                    |authorsForm.class

The applicaton can be started by using the following url:

http://localhost:8080/authors.jsp

About cuppajavamattiz
Matty Jacob - Avid technical blogger with interests in J2EE, Web Application Servers, Web frameworks, Open source libraries, Relational Databases, Web Services, Source control repositories, ETL, IDE Tools and related technologies.

Comments are closed.

%d bloggers like this: