DWR version 2 - New and Noteworthy

Version 2 contains 3 big new features and a host of smaller ones.

For the impatient: Download DWR.

Important note: DWR version 2.0.1 and before contained 2 XSS vulnerabilities. You are advised to upgrade to the latest version.

JavaScript Proxy API

DWR can dynamically generate JavaScript from a Java API. This is done at runtime rather than compile time, so we can use it to remote control many browsers. This makes it very easy to write things like chat applications, or anything particularly dynamic. Messages are sent to clients using Reverse Ajax.

DWR currently features Java APIs to Script.aculo.us Effects and DWR's own DHTML library. We'll be adding more soon.

import org.directwebremoting.proxy.scriptaculous.Effect;

Effect effect = new Effect(aBrowser);
effect.fade("id");

Reverse Ajax

DWR supports 3 ways to asynchronously transfer messages from the server to the browser: Comet (long-lived HTTP connections), Polling and Piggyback. Of these Comet and Polling are active (fast but require extra network traffic) and Piggyback is passive (slower but doesn't need extra network traffic). DWR automatically selects the best method transparently to the programmer.

Since chat is the "Hello, World" of Ajax this is our chat example:

WebContext wctx = WebContextFactory.get();
String chatPage = wctx.getCurrentPage();

// Find all the browser on window open on the chat page:
Collection sessions = wctx.getScriptSessionsByPage(chatPage);

// Use the Javascript Proxy API to empty the chatlog <ul> element
// and re-fill it with new messages
Util utilAll = new Util(sessions);
utilAll.removeAllOptions("chatlog");
utilAll.addOptions("chatlog", messages, "text");

// That's it.

DWR takes care of comet and polling, of distinguishing multiple windows in a single browser, and of fixing bugs in IE.

Other uses for this technology include progress bars, online games, stock tickers and any system where server state changes and we need to push updates to a browser or browsers.

Security

Two of the the biggest generic dangers to ajax applications today are Cross-Site Scripting (XSS), which most people are aware of, and the new tool in the hack-box: Cross-Site Request Forgery (CSRF). DWR helps you protect your site against these attacks by providing automatic protection against CSRF attacks for many configurations, and by defaulting to a mode where XSS attacks are reduced.

Other New Features

Much Expanded WAR File

The dwr.war download is significantly larger than in version 1.1. It contains a number of demos and worked examples all with fully explained source code.

Among these expanded demos is an integration with TIBCO GI that uses Reverse Ajax and the Open Ajax Hub.

New 'Script' Scope for Ajax Pages

With normal servlets there are 4 scopes; application, session, page and request. DWR2 introduces a new scope: 'script'. Script scope applies to a single web page (rather than a whole browser), however long the page lives. It works even when cookies are turned off. Script scope is available programmatically:

WebContextFactory.get().getScriptSession().setAttribute("key", value);

And also to Creators in dwr.xml:

<create creator="new" javascript="Test" scope="script">
  <param name="class" value="com.example.Test"/>
</create>

Spring Namespace Support

You can now do away with dwr.xml and replace it with configuration in your Spring Beans XML file like this:

<beans>
  <bean id="Clock" class="com.eg.Clock">
    <property name="foo" ref="foo"/>
    <dwr:remote javascript="Clock"/>
  </bean>
  ...
</beans>

Guice Support

DWR now supports Guice. Thanks to Tim Peierls, DWR and Guice play really well together. You can read more about the background on Tim's blog.

Cross Domain Ajax: <script> Tag Manipulation

Should you need to access servers in a different domain we've enabled a new remoting scheme. From DWR 2.0 you can use manipulation of <script> tags in addition to XMLHttpRequest or iframes.

Jetty Continuations

The ongoing work with Reverse Ajax is to ensure that no webservers get hurt as a result of the extra load. The first piece of the puzzle is from Jetty. If Reverse Ajax is turned on in a Jetty servlet engine then DWR will automatically use Jetty's Ajax Continuations to save on server threads.

Template-based HTML Updates

dwr.util (the new name for DWRUtil) has a new function. dwr.util.cloneNode(elementId) enables you to use HTML fragments as templates that are repeated. For example:

// Loop over all the beans
for (var i = 0; i < beanArray.length; i++) {
  // Fill in the blanks in the template.
  dwr.util.setValues(beanArray[i]);
  // Clone the parent node so we don't overwrite it next time
  dwr.util.cloneNode("template");
}
 
// Finally hide the template
dwr.util.byId("template").style.display = "none";

Automatic <signatures> in Java5+

DWR 1.x sometimes needs a <signatures> element to help it get the type conversion right. If you are using DWR 2.0 with JDK5 generic types then you probably don't need <signatures> any more. DWR will automagically get the right type conversion.

Annotations

If you are using Java 5 then you can make use of the new DWR annotations. New annotations include @RemoteProxy, @DataTransferObject, @RemoteMethod and @RemoteProperty. For more detail see the annotations documentation.

Servlet Session Timeout Support

A number of security mechanisms automatically send a login page back to the user if some security constraint times out. DWR2 enables you to define what to do if a timeout occurs. Commonly a simple page reload is all you need:

dwr.engine.setTextHtmlHandler(function() {
  document.location.reload();
});

Other Stuff

There are hundreds of other small changes too small for this list that make DWR 2 a great release. Please tell us what you think on the DWR mailing list.