Client Side Validation

Validation is a very important aspect of any web application.We can validate user input in client side as well as server side. Client side validation is important since we dont want to send data to server and thenlet user know about the errors. But we can not rely only on client side validation since if Javascript is disabled on client side it will lead to invalid data on server.
So mix approach should be followed: validating data on server as well as client side.


I am using Spring Framework and Spring MVC, I have few options available:


  1. AJAX based validation
  2. Spring VLANG Validation
  3. Apache commons validation (Struts Validator Framework)

I have dropped idea of AJAX based validation since it will require to more Remote calls
Spring VLANG Validation is a good option but dependency is JDK 1.5 and we are still running on JDK 1.4.

Finally decided to go for Commons validator this is well proven and stable one.
I have also read blog from Matt where he appreciated commons validator.
I have used custom validation along with commons standard validation.

Steps followed by me to get commons validator configured with Spring are as follows:
Dependency:
1. Spring-commons-validator (Spring modules 0.8)
2. Commons validator

Step 1: Downloaded dependency jar files
Step 2: Added validation.xml, validation-rules.xml, validation-custom-rules.xml (For custom validators)
Step 3: Added validation specific entries to applicationContext-validation.xml
step 4: Added validator property to form controller entry in [context-root]-servlet.xml

My Validation.xml is as follows:

Validation.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1//EN" "http://jakarta.apache.org/commons/dtds/validator_1_1.dtd;
<form-validation>
<formset>
<form name="registerFormBean">
<field property="user.fname" depends="mask,maxlength">
<arg0 key="register.label.firstname"/>
<arg1 name="maxlength" key="${var:maxlength}" resource="false"/> <var><var-name>maxlength</var-name><var-value>5</var-value>
</var> <var> <var-name>mask</var-name> <var-value>^[a-zA-Z]*$</var-value> </var>
</field> <field property="user.email" depends="required,email">
<arg0 key="register.label.email"/>
</field> <
field property="user.password" depends="required,twofields">
<arg0 key="register.label.password" />
<arg1 key="register.label.verifypassword"/>
<var> <var-name>secondProperty</var-name>
<var-value>verifyPasswd</var-value>
</var> </field> <
field property="verifyPasswd" depends="required">
<arg0 key="register.label.verifypassword" />
</field>
<field property="user.location" depends="selectfield">
<arg0 key="register.label.location" />
<arg1 key="${var:maxsize}" name="selectfield" resource="false"/>
<var><var-name>maxsize</var-name><var-value>3</var-value></var>
</field>
</form>
</formset>
</form-validation>

Validation-rules-custom

My custom validation rules file is as follows:

<!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN" "http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd; <form-validation>
<global>


<validator name="twofields" classname="com.tj.cand.utils.ValidationUtil" method="validateTwoFields"

methodParams="java.lang.Object,

org.apache.commons.validator.ValidatorAction,

org.apache.commons.validator.Field,

org.springframework.validation.Errors"

depends="required" msg="errors.twofields">

<javascript><!

[CDATA[ function validateTwoFields(form) {

var bValid = true;

var focusField = null;

var i = 0;

var fields = new Array();

oTwoFields = new twofields();

for (x in oTwoFields) {

var field = form[oTwoFields[x][0]];

var secondField = form[oTwoFields[x][2]("secondProperty")];

if (field.type == 'text' field.type == 'textarea' field.type == 'select-one' field.type == 'radio' field.type == 'password') {

var value; var secondValue;

// get field's value

if (field.type == "select-one") { var si = field.selectedIndex; value = field.options[si].value; secondValue = secondField.options[si].value; } else { value = field.value; secondValue = secondField.value; } if (value != secondValue) { if (i == 0) { focusField = field; } fields[i++] = oTwoFields[x][1]; bValid = false; } } } if (fields.length > 0) { focusField.focus(); alert(fields.join('\n')); } return bValid; }]]> </javascript> </validator> <validator name="selectfield" classname="com.tj.cand.utils.ValidationUtil" method="validateSelectField" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, org.apache.commons.validator.Field, org.springframework.validation.Errors" depends="" msg="errors.multiselect"> <javascript><![CDATA[ function validateSelectField(form) { var bValid = true; var focusField = null; var i = 0; var fields = new Array(); oSelectFields = new selectfield(); for (x in oSelectFields) { var field = form[oSelectFields[x][0]]; if (field.type == 'select-multiple') { var iMax = parseInt(oSelectFields[x][2]("maxsize"));
if ((field.options.length == 0) (field.options.length > iMax)) { if (i == 0) { focusField = field; } fields[i++] = oSelectFields[x][1]; bValid = false; } } } if (fields.length > 0) { focusField.focus(); alert(fields.join('\n')); } return bValid; }]]> </javascript> </validator> </global>
</form-validation>

Installing DBD::MySql

I had spent last two days trying to install DBD::MySql version-4.005 for mySql 5.1-22.0 rc.

After a lot of permutation and combination finally able to get it done. I have seen a lot of discussion forums but not able to get the root cause of the problem finally I figured out that it was related with MySql Devel rpm and static linking of My sql Client Library.

This is a known issue with DBD::MySql. It fails if you try linking MySql Client library Dynamically.

The steps I followed after going through DBD::MySql documentation are as follows:

1. Install Mysql-Client rpm
2. Install MySql-Devel Library
3. Install MySql Shared Libraries

  • MySQL-client-community-5.1.22-0.rhel
  • MySQL-devel-5.1.22-0.glibc23
  • MySQL-shared-compat-5.1.22-0.rhel4
Installing DBD::MySql

1. tar xvzf DBD-mysql-.tar.gz
2. cd DBD-mysql-
3. cp /usr/lib/mysql/*.a /tmp/mysql-static (to link libmysql.client.a statically)
4. perl Makefile.PL --libs="-L/tmp/mysql-static -lmysqlclient" --testuser=user --testpassword=pass
5. make
6. make test
7. make install

All tests passed successfully.

Resources:

AJAXing with Spring using DWR

Recently I have an opportunity to work with Spring Framework. With Spring I have used following technologies:

1. Spring MVC
2. Ajax - DWR
3. Hibernate
4. Tiles
5. Acegi Security

It was really a nice experience working with Spring and other supporting technologies.

I found a littlet bit problem in getting DWR 2.0 working with Spring 2.0.

Approach that worked for me as follows:

1. Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4">
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<!-- Listner Config-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<!-- Ajax DWR config ends -->
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
<servlet>

2. Application-Context.xml

<!-- DWR Configurations -->
<dwr:controller id="dwrController" debug="true"/>
<!-- Configure DWR handlers -->

<bean id="dwrUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="alwaysUseFullPath" value="true"/>
<property name="mappings">
<props>
<prop key="/dwr/**/*">dwrController</prop> </props> </property>
</bean>
<!-- Configure Convertor -->

<dwr:configuration>
<dwr:convert type="bean" class="com.app.domain.User" />
</dwr:configuration>

<!-- Configure Ajax controller -->

<bean id="ajaxController" class="com.app.controller.dwr.AjaxController">
<dwr:remote javascript="UserList">
<dwr:include method="getUser"/>
<dwr:include method="updateUser"/>
</dwr:remote>
<property name="userDao" ref="userDao"/>
</bean>

3. JSP Page

Add following lines to jsp page:
<script type='text/javascript' src='/spring/dwr/interface/UserList.js'></script>
<script type='text/javascript' src='/spring/dwr/engine.js'></script>
<script type='text/javascript' src='/spring/dwr/util.js'></script>

Define call back javascript function and attach that to some event

<script type="text/javascript">
function editUser(id) {
UserList.getUser(id,function(array){DWRUtil.setValue(fname,array.fname); });
}
</script>

Finally deploy the application and restart the server and here is your DWR wroking...

To test it you can use: http://localhost:8080/spring/dwr/index.html

Resources: