Developing Applications Using Reverse Ajax Blog

Version 2


    Ajax has long been known for providing an enhanced user experience, allowing a web page to be updated using data from a web server without the need for a full page refresh. Now, however, web developers are increasingly requiring Ajax applications to update page data, not only when the user sends a request, but also when the server decides an update is required. Examples of this include a multi-user application, where all users need to be aware of the changes other users make, or a monitoring application, with the server needing to let the browser know that its state has changed.

    In such situations, developers of Ajax applications can employ various techniques to ensure this "push" from the server to the browser occurs. But which technique is best for which situation? Answering this question and then implementing it can be a lengthy process. This article will investigate one answer to this problem.

    DWR, hosted on, is a Java open source library that helps developers to write websites that include Ajax technology. When DWR broke onto the Ajax scene with release 1.0, its announced mantra was "Easy Ajax for Java." It aids the developer in many ways, not least by allowing code in the web browser to use Java functions running on the web server as if they were in the browser.

    With release 2.0, DWR continues on the same theme, removing from the developers shoulders the pesky problem of "pushing" information. It introduces the term reverse Ajax to describe this asynchronous transfer of messages from server to browser or browsers. While, as mentioned above, techniques for doing this already exist, the beauty of "reverse Ajax" is that it wraps them all up neatly and then automatically selects the best method to use transparently to the user.

    The three techniques DWR supports are:

    At regular and frequent intervals, the browser sends requests to the server to see if the page has been updated.
    After a request has been received from the browser, the server keeps the reply open so that it can pass down information when it arrives. This is also known as a long-lived HTTP connection.
    When the server has an update to send, it waits for the browser to make a request and then sends the update in addition to the requested information.

    When comparing the three techniques above, it is easy to see that when using the polling or comet techniques, updates from the server to the browser would occur quicker than when using piggyback. However, polling and comet have the disadvantage of producing extra network traffic, while piggyback does not.

    DWR recognizes that speed of updates and amount of network traffic will be something the developer wants to have a hand in controlling. Therefore, it separates the three techniques into two categories: comet and polling are classed as active, and piggyback is classed as inactive. If the developer requires a faster "push" of information from the server to the browser, and is willing to take the hit of extra network traffic, she can enableactive reverse Ajax. This allows comet and polling to be brought into the equation when DWR is deciding which technique to use. If active reverse Ajax is not enabled, then piggyback is used. In this way, reverse Ajax is always available even when active reverse Ajax is turned off.

    So how does DWR's reverse Ajax make things easy for the developer?

    The example below aims to demonstrate how easily we can add a chat web page using reverse Ajax to an existing web application. The web page is a simple multi-user chat demo, allowing a number of users to see the messages that each submits. Reverse Ajax is used to collect the messages, and server-side browser manipulation updates the pages with the results. The emphasis is not on fancy graphics, but on demonstrating how simply the chat functionality can be added and how easily we can implement reverse Ajax. The source to the chat example is included with the DWR 2 distribution.

    First, we will look at how the JavaChat web page and the server-side Java are constructed. Then we will add the reverse Ajax code to show how easily it can be implemented.

    The JavaChat Web Page

    The web page consists of two parts: the first is an input field where you can type a message; the second is the area where you can see the messages that you have typed. This is also the area where messages will appear from other users. Figure 1 shows what it looks like.

    The chat web page
    Figure 1. The JavaChat web page

    The HTML is very simple:

    <h1>Java Chat</h1> <p>This is a very simple chat demo that uses reverse ajax to collect messages and server-side browser manipulation to update the pages with the results.</p> <p> Your Message: <input id="text" onkeypress="dwr.util.onReturn(event, sendMessage)"/> <input type="button" value="Send" onclick="sendMessage()"/> </p> <hr/> <ul id="chatlog" style="list-style-type:none;"> </ul> 

    A few lines of JavaScript are also included. The JavaScript calls the Java code that will do the work.

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

    Here engine.js contains the core of DWR; util.jscontains some optional utility functions for use with DWR; andJavaChat.js is the JavaScript dynamically generated by DWR as the remote version of, the Java class we shall view in more detail below. Full documentation for engine.js and util.js can be seen at the DWR website.

    A JavaScript function is also included to be fired off by the browser whenever the Send button is pressed.

    <script type="text/javascript"> function sendMessage() { JavaChat.addMessage(dwr.util.getValue("text")); } </script> 

    This calls the addMessage() method in theJavaChat class, as we shall below.

    Server-Side Java

    We have two classes to do the server-side work. The first is theMessage class. This holds a single string entered by the user. The Message also maintains a unique ID as a property. For now, we are going to cheat by using the current time in milliseconds as the ID.

    import org.directwebremoting.Security; public class Message { public Message(String newtext) { text = newtext; if (text.length() > 256) { text = text.substring(0, 256); } text = Security.replaceXmlCharacters(text); } public long getId() { return id; } public String getText() { return text; } private long id = System.currentTimeMillis(); private String text; } 

    The constructor does a few simple things: it shortens the messages to 256 characters and uses the DWR Securityclass to ensure that the characters are valid.

    The other class on the server is the JavaChatclass. It keeps track of the messages sent to the server.

    public class JavaChat { public void addMessage(String text) { if (text != null && text.trim().length() > 0) { messages.addFirst(new Message(text)); while (messages.size() > 10) { messages.removeLast(); } } //Reverse Ajax code to be added here shortly } private LinkedList messages = new LinkedList(); protected static final Logger log = Logger.getLogger(JavaChat.class); } 

    As mentioned earlier, addMessage() is called in response to a user typing in the input area, the textparameter being the new text to add to the list. The code ensures that only the last ten messages are held in the list.

    Now we have the basic code written; where should the reverse Ajax code be added to ensure that the information can flow from the server to the browser?

    Implementing Active Reverse Ajax

    Reverse Ajax is implemented in three places. TheJavaChat web page, the JavaChat class and the web.xml file.

    In the JavaChat web page, the following line should be included, allowing active reverse Ajax (ARA) to occur.

    <body onload="dwr.engine.setActiveReverseAjax(true);"> 

    The main code change occurs in the JavaChat class. The following lines should be included in theaddMessage() method. You may have noticed the comment above that indicates where it should be inserted.

    WebContext wctx = WebContextFactory.get(); String currentPage = wctx.getCurrentPage(); // Clear the input box in the browser that kicked off this page only Util utilThis = new Util(wctx.getScriptSession()); utilThis.setValue("text", ""); // For all the browsers on the current page: Collection sessions = wctx.getScriptSessionsByPage(currentPage); Util utilAll = new Util(sessions); // Clear the list and add in the new set of messages utilAll.removeAllOptions("chatlog"); utilAll.addOptions("chatlog", messages, "text"); 

    As part of configuring your app server's web.xml to understand DWR, the following lines of code need to be added to theweb.xml file. You will notice a parameter calledpollAndCometEnabled with its value set totrue. By setting the value to true we ensure that active reverse Ajax is turned on and polling or comet techniques can be used.

    <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWR Servlet</display-name> <description>Direct Web Remoter Servlet</description> <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>pollAndCometEnabled</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> 

    Configuring DWR

    The first step in configuring DWR is to copy dwr.jar into your web app. You can download dwr.jar from its project. Next, you need to tell DWR about the chat server you have just created. The DWR configuration file dwr.xml file should be placed alongside web.xml in your WEB-INF folder. For your chat application, dwr.xml should look like this:

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" ""> <dwr> <allow> <create creator="new" javascript="JavaChat"> <param name="class" value="
    [your.package].JavaChat"/> </create> <convert converter="bean" match="
    [your.package].Message"/> </allow> </dwr> 

    In the code above, [your.package] should be replaced with the package that you used.

    We are telling DWR it is OK to create JavaChatclasses for remoting to the browser, and that in JavaScript they will be called JavaChat. It also says thatMessage is safe to be used as a parameter.

    And that's it! We have a basic multi-user, web-based chat system that uses reverse Ajax with active reverse Ajax turned on, in under 200 lines of code.


    Using DWR version 2.0 can make it very easy to add chat functionality to an application, allowing updates to be pushed from the server to the browser or browsers so that all users are aware of changes made. DWR's reverse Ajax introduces a very neat way to manage this transfer of information. It takes responsibility for deciding which techniques (polling, comet or piggyback) are best to use in each situation. It is easy to implement, thereby leaving the programmer free to concentrate on developing other areas of her application.