Spring and DWR – Ajax made Easy

by Bram SmeetsJanuary 31, 2007

Direct Web Remoting (DWR) is an Open Source initiative that provides easy Ajax for Java. Besides being the best Ajax framework for Java developers, it has one more big feature, at least in my opinion. It integrates very nicely with Spring, by provides the means to easily remote your spring-managed beans to JavaScript. However, up until now there has always been a very loose coupling between the DWR configuration and the Spring configuration. For more information on how DWR was configured to work with Spring in the past see one of my earlier post on using DWR in conjunction with Spring (note that it is fairly outdated).

Configure DWR in Spring

Joe and I are pleased to announce that a new configuration mechanism is available when using DWR in conjunction with Spring. Using the new namespace support provided by Spring 2.0 it is possible to incorporate the DWR configuration you would normally configure in your dwr.xml, into your Spring configuration. This means that when using Spring you will no longer need to create a separate dwr.xml, but configure DWR entirely in Spring instead. Next to eliminating the need for an extra configuration file, it also provides a tight coupling between the bean(s) you want to remote and the DWR configuration. Previously this was done by specifying the name/id of the bean you wanted to remote in your DWR configuration. As you will see in a moment, you can now specify the fact that you want to remote a certain bean directly onto that specific bean. This leads to a much more intuitive, readable and maintainable configuration. Two other advantages of using this new way of configuration are that first of all this eliminates the problems we had when directly remoting proxied beans (e.g. transactional services) and secondly eliminates the limitation we had in the past that you could only remote beans that were loaded by a ContextLoaderListener and not those defined in your xxx-servlet.xml.

Of course you do not need to use this new configuration mechanism, you can choose to keep using the old way of configuring DWR. But if you take a look at the new mechanism, I am fairly sure that you will be just as enthusiastic as I am about this new feature!

Please note that the DWR namespace is only available when using DWR version 2.0-rc2 or higher. It is also heavily dependent on the namespace support provided by Spring 2.0, so you need to include this on your classpath as well (preferably the latest version, currently 2.0.2).

Enough talk, let us have a look at sample configuration. Assume the following Spring configuration file:

<br>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
&lt;beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br>
       xsi:schemaLocation="http://www.springframework.org/schema/beans<br>
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"><br>
  &lt;bean id="myService" class="example.MyServiceImpl"&gt;<br>
    &lt;property name="dao" ref="myDao"/&gt;<br>
  &lt;/bean&gt;<br>
&lt;/beans&gt;<br>

First of all, note that we are using the Spring namespace support in the header of the XML document instead of the Spring DTD. This is something which is available since Spring 2.0 and is inherent to using the namespace support. The ajaxFacade bean is just an ordinary bean configured in Spring which has a reference to some Data Access Object (DAO) defined in another application context.

Now, we decide we want to remote this bean to JavaScript using DWR. In that case we need to include the DWR namespace into the header of the document. To include it we change the header to the following:

<br>
&lt;beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br>
       xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"<br>
       xsi:schemaLocation="http://www.springframework.org/schema/beans<br>
       http://www.springframework.org/schema/beans/spring-beans.xsd<br>
       http://www.directwebremoting.org/schema/spring-dwr<br>
       http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd"><br>

First of all you need to define the XML namespace (xmlns) by providing an alias, in this case dwr and link it to the URI of the schema. Note that the dwr alias can be replaced with anything you want as long as you use your alias in the next examples instead of the dwr one. Changing xmlns:dwr to xmlns:otheralias is all you need to do to change the alias.

Alright, so far for the “hard” part, everything from here will be easy

If you have an IDE with XML schema support (e.g. IntelliJ and Eclipse) you should navigate inside the myService bean and use the autocomplete functionality to show you all available tags provided by the DWR namespace.

Choose the dwr:remote tag and you will see that the IDE will automatically prompt you for the javascript name to use for exposing the bean. Note that the dwr:remote tag should be a nested tag of the myService bean. So now, the bean myService bean definition should look like the following:

<br>
&lt;bean id="myService" class="example.MyServiceImpl"&gt;<br>
  &lt;dwr:remote javascript="MyAjaxService"/&gt;<br>
  &lt;property name="dao" ref="myDao"/&gt;<br>
&lt;/bean&gt;<br>

Now, that is all there is to it to configure DWR to remote the myService bean under the JavaScript name “MyAjaxService”. However, we do need to somehow expose DWR to the outside world. Here you have two possibilities where the choice is mostly dependent on whether you are using Spring MVC for your web application in which case you should go with the DwrController or using any other web framework then go with the DwrSpringServlet.

DwrController

If you are already using Spring MVC the DwrController is the most obvious choice. You will benefit from a number of services provided to you by Spring MVC, like localization support. The DwrController is a normal Spring controller which has a property that takes the DWR configuration as a property. The easiest way to use this controller is again use a tag provided by the DWR namespace:

<br>
&lt;dwr:controller id="dwrController" debug="true"/&gt;<br>

Note that the debug property is optional and defaults to false. Make sure to map this controller to the path where you want to expose DWR, normally /dwr.

DwrSpringServlet

In case you are not using Spring MVC, you can still use the configuration mechanism introduced here. Just define the org.directwebremoting.spring.DwrSpringServlet in your web.xml and map it to the /dwr/* path. The servlet will automatically retrieve its configuration from the Spring bean container loaded by the ContextLoaderListener.

<br>
&lt;servlet&gt;<br>
  &lt;servlet-name&gt;dwr&lt;/servlet-name&gt;<br>
  &lt;servlet-class&gt;org.directwebremoting.spring.DwrSpringServlet&lt;/servlet-class&gt;<br>
  &lt;init-param&gt;<br>
    &lt;param-name&gt;debug&lt;/param-name&gt;<br>
    &lt;param-value&gt;true&lt;/param-value&gt;<br>
  &lt;/init-param&gt;<br>
&lt;/servlet&gt;</p>
<p>&lt;servlet-mapping&gt;<br>
  &lt;servlet-name&gt;dwr&lt;/servlet-name&gt;<br>
  &lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;<br>
&lt;/servlet-mapping&gt;<br>

I have uploaded a sample skeleton application, which should get you started with using these new features:

DWR-Spring skeleton application