Thursday, May 17, 2007
Direct Web Remoting - A Tutorial
The DWR / Direct Web Remoting is an open source solution under the Apache license for the developer who wants to use AJAX and XMLHttpRequest in an easy way.
A Step by Step example:
1) Create the java service class :
package com.example.dwr;
public class DWRPersonService {
public Person[] getAllPersons() {
Person[] list = new Person[3];
/* .............................
Call your Ejb / DAO here
and populate values in the array
.............................
*/
Person info = null;
info = new Person();
info.setId(1L);
info.setName("sam");
info.setCity("bangalore");
info.setCountry("india");
list[0] = info;
return list;
}//end of getAllPersons
}//end of Class
2) Create the java bean class. (can be your Info or Transfer Object)
package com.example.dwr;
public class Person {
private Long id;
private String name;
private String city;
private String country;
/*
* Getters and Setters are defined here
*/
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
// ...............
}//end of Class
3) Configure DWR in WebXml
Start by specifying DWR's existence in the web.xml
<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> </servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</servlet>
Include dwr.jar in the WEB-INF/lib folder.
Place the scripts and css files in the respective folders.
You can download the latest jar from DWR Site
For support of autocomplete feature download the script.aculo.us-js-1.x.zip
4) Configure the dwr.xml
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<create creator="new" javascript="JDate">
<param name="class" value="java.util.Date"/>
</create>
<create creator="new" javascript="DWRPersonService">
<param name="class" value="com.example.dwr.DWRPersonService"/>
<include method="getAllPersons" />
</create>
<convert converter="bean" match="com.example.dwr.Person"></convert>
</allow>
</dwr>
We specify here to create a new js file for DWRPersonService.
The DWR engine will generate a file DWRPersonService.js at runtime
with the function getAllPersons.
The DWRPersonService.js created at run time by DWR Engine, looks as follows:
// Provide a default path to dwr.engine
if (dwr == null) var dwr = {};
if (dwr.engine == null) dwr.engine = {};
if (DWREngine == null) var DWREngine = dwr.engine;
if (DWRPersonService == null) var DWRPersonService = {};
DWRPersonService._path = '/dwr-sample/dwr';
DWRPersonService.getAllPersons = function(callback) {
dwr.engine._execute(DWRPersonService._path, 'DWRPersonService', 'getAllPersons', callback);
}
5) Create your Jsp.
Include the following js files from DWR.
<script type='text/javascript'
src='<%= request.getContextPath() %>/dwr/engine.js' />
<script type='text/javascript'
src='<%= request.getContextPath() %>/dwr/util.js' />
Also include the js file created for you, as defined in dwr.xml
<script type='text/javascript'
src='<%= request.getContextPath() %>/dwr/interface/DWRPersonService.js' />
Include the following js and css files for AutoComplete feature.
<link rel="stylesheet" type="text/css"
href="<%=request.getContextPath() %>/styles/autocomplete.css"/>
<script type="text/javascript" src="<%= request.getContextPath() %>/scripts/prototype/prototype.js"/>
<script type="text/javascript" src="<%= request.getContextPath() %>/scripts/script.aculo.us/effects.js"/>
<script type="text/javascript" src="<%= request.getContextPath() %>/scripts/script.aculo.us/controls.js"/>
<script type="text/javascript" src="<%= request.getContextPath() %>/scripts/autocomplete.js"/>
Create a text field with id personName. Create a div with the class auto_complete.
Instantiate the function AutoCompleter which takes the following arguments.
i)Id of the textField
ii)Id of the autocomplete Div for this textField
iii)function to populate the list – uses DWR
iv)Optional arguments like valueSelector – property to be listed from the Bean object, chioces – maximum number of choices to be displayed etc.
Finally, call the method DWRUtil.useLoadingMessage on body onLoad.
<script language="javascript">
function updatePersonList(autocompleter, token) {
DWRPersonService.getAllPersons(function(data) { autocompleter.setChoices (data); });
}
</script>
<body onload="DWRUtil.useLoadingMessage();">
Search Person: <input id="personName" type="text" style="width:250px;" / >
< div id="personListDiv" class="auto_complete" > </div>
<script type="text/javascript">
new Autocompleter.DWR('personName', 'personListDiv', updatePersonList,
{ valueSelector: function(obj){ return obj.name; }, partialChars: 1, choices: 10 });
</script>
</body>
In the above method the arguments are as follows :
new AutoCompleter.DWR(textFieldName, associatedDivName, methodForPopulatingList, optionalParams)
OptionalParams:
ValueSelector : the property of the bean that has to be shown in the autocomplete list. For example, 'name' property from 'Employee' bean.
PartialChars : Minimum number of characters to be entered in order to begin matching. Default value is 2.
Choices : Maximum number of items to be shown in the drop down.
Run your application and see DWR in action !!!