Sunday, May 25, 2008

How to integrate DWR and Struts

DWR is AJAX framework for JAVA. Using DWR you can call directly any method of java class asynchronously ie. without entire page reload. With following you can even integrate DWR with struts so as to have access to important formbeans and also any other java classes. Only restriction being : methods to be called has to be form methods. This is easily done by refactoring code in Action class to form class. By this way you can call this code from Action class as well as via ajax.

Add dwr.jar to web project

Modify Web.xml Add following code to web.xml. Make sure DWR servlet gets loaded after ActionServlet.


<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>100</param-value>
</init-param>
<!--
<init-param>
<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>
<param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>
</init-param>
-->
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>



Create dwr.xml file. This file will tell DWR which classes are to be exposed for asynchronous calls. Following example file exposes PersonFrom class using interface name Forms using Struts Creator. It also exposes Date class as remote class JDate.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr//dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="JDate">
<param name="class" value="java.util.Date" />
</create>
<create creator="struts" javascript="forms">
<param name="formBean" value="personForm" />
</create>
<convert converter="bean" match="$Proxy*" />
</allow>
</dwr>


Include following lines in JSP for adding DWR javascripts. “forms.js” refers to our “forms” class exposed in dwr.xml. These files do not exist physically but are dynamically generated and served by DWR servlet.

<script type='text/javascript' src='dwr/engine.js'> </script>
<script type='text/javascript' src='dwr/util.js'> </script>
<script type='text/javascript' src='dwr/interface/forms.js'> </script>


Now you can call any method of form PersonForm class. PersonForm class has method called generateAntiSpamMailto. You can directly call this method using javascript. See following example. Following example basically dynamically calls “generateAntiSpamMailto” method on server to get anti-spam text and puts in to the div and makes the div visible. This is done by defining function as the third argument. First two arguments are regular arguments which are same as java arguments.


function process() {
var address = dwr.util.getValue("address");
var name = dwr.util.getValue("name");
alert('Addres is ' + address);
alert('Name is ' + name);

forms.generateAntiSpamMailto(name, address, function(contents) {
alert('content is ' + contents);
dwr.util.setValue("outputFull", contents, { escapeHtml:false });
dwr.util.byId("output").style.display = "block";
});
}

and HTML part as


<input id="submit" type="button" value="Submit Query" onclick="process()"/>
<html:submit>Submit Query</html:submit>
</html:form>

<div id="output" style="display:none;">
<h2>Generated Links</h2>
<textarea id="outputFull" rows="9" cols="70">
</textarea>
</div>


You can even use DWR to validate certain field on the spot when user finishes typing the data. Validation will be done on the server but called asynchronously via AJAX. Following is an example which makes use of Apache Commons Validator framework to validate an email address. This require certain jars to added to lib(BSF, BSH,Commons jars included in the zip file attached).

DWR xml

<create creator="script" javascript="EmailValidator" scope="application">
<param name="language" value="beanshell"/>
<param name="script">
import org.apache.commons.validator.EmailValidator;
return EmailValidator.getInstance();
</param>
</create>

and HTML /JavaScript part

<script>
function verifyAddress() {
var address = dwr.util.getValue("address");
EmailValidator.isValid(address, function(valid) {
dwr.util.setValue("addressError", valid ? "" : "Please enter a valid email address");
});
}
</script>

<html:text property="name" size="16" onkeypress="dwr.util.onReturn(event, process)" onblur="verifyAddress()"/>

3 comments:

Nicola said...

Hi,
I have some problems integration with DWR and Struts. In my application I use DynaActionForm. I want to use another way, but, I'm using also some BusinessInterface to get data from database. To use business class I need the request, but at same time I can't use my Action class with dwr. What do you suggest me to do?

Thank in advantage.
Nicola

chrc said...

Hi Tushar !

Thank a lot for your article about dwr and struts.

I want use dwr (2.x or 3.x version) with STRUTS 2 actions and dwr annotations !
How can i do that ?

thx and best regards.

Chris

Yogesh P said...

Can i get source code of this example ???
where is attached zip file ?