Friday, September 18, 2009

Implementing Direct Web Remoting ( DWR) in Spring Framework

Introduction

Direct web remoting or DWR is like 'AJAX made simple for JAVA'. It is a Java library that helps JavaScript in a browser to interact with Java code on the server.

AJAX VS DWR


In most of the cases, AJAX works in 'pull' mode; pulling data from server by calling server side resource(s), such as jsp, php, servlet, etc... from some browser script/JavaScript code.

In Ajax world, you basically call server resource(s) asynchronously using magical object called 'XMLHTTPRequest' and also define callback method to handle data/message returned from server.

In case of DWR; It can work in both the modes, push as well as pull.

In pull mode DWR library makes java class available to the JavaScript code in the browser. So you can directly call methods on Java class from JavaScript code. Also you may need to define callback method and pass it as parameter to the method of the Java class.

The DWR's push mode is called 'reverse ajax', which pushes data to the browser from the server. There are three methods to implement reverse ajax: Polling, Comet, and Piggyback. Here is a quick definition: (Get more info here : http://directwebremoting.org/dwr/reverse-ajax/index.html)

Polling:

Browser makes call to the server in frequent and regular intervals.

Comet:

This is also called long lived http, server push. In this case http session is open for longer time dictated and scheduled by the server.

Piggyback:

Server keeps update ready and waits for browser for the next http request. Once it receives, it appends its update/message along with response to the current http request.

DWR in Spring


So far what I have discussed above is high level overview and how things works in a nutshell. Let's dive deep and see how DWR can be put to work in Spring MVC. Here is step by step process:

Step 1

First step would to download latest dwr.jar from DWR web site and reference it in your Spring web project
Next a java class/pojo needs to be defined, which would server as class instance to be called from javascript, like this:-


public class AcsDWRUtil {

private volatile SubCategoryDAO subcategoryDAO;

public SubCategoryDAO getSubcategoryDAO() {

return subcategoryDAO;

}

public void setSubcategoryDAO(SubCategoryDAO subcategoryDAO) {

this.subcategoryDAO = subcategoryDAO;

}

public String[] getBusinessSubCategories(int catId) {

List subCatList = this.subcategoryDAO

.getSubCategoriesAsStringList(catId);

if (subCatList.size() > 0) {

String[] subCatStrArr = new String[subCatList.size()];

return subCatList.toArray(subCatStrArr);

} else {

return null;

}

}

}


Step 2

Next step is to add DWR namespace and schema location in your Application context's 'beans' tag. Here is an example:


<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-2.0.xsd

http://www.directwebremoting.org/schema/spring-dwr

http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">


Step 3


Now a configuration tag needs to be added to Application context. This is required even if it does not have data with in it.


<dwr:configuration>dwr:configuration>


Step 4

Configure bean/class (defined in the Step 1) in the Application Context file. It also has dwr tag which basically enables JavaScript to call method on that object instance.


<bean id="dwrService" class="util.AcsDWRUtil" >

<dwr:remote javascript="dwrService">

<dwr:include method="getBusinessSubCategories" />

dwr:remote>

<property name="subcategoryDAO" ref="subcategoryDAO" />

bean>


Tag dwr:remote enables JavaScript to invoke method(s) on dwrService.

Here is an example how jsp page would call DWR. Bur before that few js files (created by DWR engine) needs to be included in the page:


<script type='text/javascript'

src='/abservice/dwr/interface/dwrService.js'>script>

<script type='text/javascript' src='/abservice/dwr/engine.js'>script>

<script type='text/javascript' src='/abservice/dwr/util.js'>script>


Here is the JavaScript code calling Java method using dwrService instance the AcsDWRUtil class:


function callbackDWRGetSubCategories(data) {

var subCatArr = data;

dwr.util.setValue("subcat", subCatArr);

}

function getSubCategories(catId) {

dwrService.getBusinessSubCategories(catId, callbackDWRGetSubCategories);

}


And finally you would be calling above getSubCategories() in your jsp page somewhere. Keep in mind you would need to add one additional parameter to the lava method. It is a js callback method as described above.

That's all. Your Spring app is now DWR enabled and enjoy the power of DWR async communication.

In the next article I am planning of covering DWR "reverse ajax".

Please shoot me an email if you have any suggestions or questions. I would be glad to answer.

Till then,

Sanjay Semwal

J2EE Architect

No comments:

Post a Comment