Friday

DWR and Reverse Ajax

Direct Web Remoting (DWR), is an open source Java library that can be used to implement Ajax in Java web applications with minimal Javascript coding. Using DWR, we can invoke server-side Java methods from Javascript in the browser. DWR 2.0 introduces a new feature, dubbed "Reverse Ajax", using which server-side Java can "push" updates to the browser. In this post, I tried to use a simplistic web application that will demonstrate the use of DWR for "Reverse Ajax".
In this example, I use a servlet that will be pushing information to the browser clients. Here is how to implement the example.

  1. Download DWR 2.0 from here, dwr.jar file has to be included in the classpath.
  2. Create the Service: This service generates messages which will be written to the browser. Here is the code for the Service.
    package utils;

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;

    import org.directwebremoting.ServerContext;
    import org.directwebremoting.proxy.dwr.Util;

    public class Service {

    private int count = 0;

    public void update(ServerContext wctx) {
    List<Data> messages = new ArrayList<Data>();
    messages.add(new Data("testing" + count++));

    // Collection sessions = wctx.getAllScriptSessions();
    Collection sessions = wctx.getScriptSessionsByPage("/ReverseAjax/index.html");
    Util utilAll = new Util(sessions);
    utilAll.addOptions("updates", messages, "value");
    }
    }

    Service.java


  3. Create the Message Container: The message container is a simple Java bean that holds the message.

    package utils;

    public class Data {
    private String value;

    public Data() {
    }

    public Data(String value) {
    this.value = value;
    }

    public String getValue() {
    return value;
    }

    public void setValue(String value) {
    this.value = value;
    }
    }

    Data.java


  4. Create the Servlet: Here is the code for the Servlet.

    package servlets;

    import java.io.IOException;
    import java.io.PrintWriter;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.directwebremoting.ServerContext;
    import org.directwebremoting.ServerContextFactory;

    import utils.Service;

    public class TestServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Service service = new Service();
    ServerContext wctx = ServerContextFactory.get(this.getServletContext());
    for (int i = 0; i < 10; i++) {
    service.update(wctx);
    try {
    Thread.sleep(1000);
    }
    catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    PrintWriter writer = response.getWriter();
    writer.println("Done");
    writer.close();

    }}

    TestServlet.java



    • The ServerContext is used by DWR to get information of the clients that have open sessions on the server.




  5. The Web Page: This is the code for the Web Page (index.html).

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>index</title>
    <script type='text/javascript' src='dwr/engine.js'></script>
    <script type='text/javascript' src='dwr/interface/Service.js'></script>
    <script type='text/javascript' src='dwr/util.js'></script>
    </head>
    <body xxxxx="dwr.engine.setActiveReverseAjax(true);">
    <ul id="updates">
    </ul>

    </body>
    </html>

    index.html



    • engine.js handles all server communications.


    • util.js helps you alter web pages with the data you got from the server.


    • The path to the scripts is relative to the root of the web content. The DWR servlet (defined in the web.xml file) will provide these scripts.


    • dwr.engine.setActiveReverseAjax(true); is used to activate Reverse Ajax


    • The id of the list is the same as the parameter set in the Service.




  6. The Web Deployment Descriptor:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>ReverseAjax</display-name>

    <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>
    <init-param>
    <param-name>activeReverseAjaxEnabled</param-name>
    <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>servlets.TestServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/testServlet</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    </web-app>

    WEB-INF/web.xml



    • The DWR Servlet has to be loaded on startup


    • Setting activeReverseAjaxEnabled to true sets Reverse Ajax to be active. In this case Reverse Ajax used will be through polling or comet requests (extended http requests). If this is false, then inactive Reverse Ajax (piggybacking) will be used. In this case, the server waits for requests from the client and piggybacks the updates with the response.




  7. The DWR Configuration: The DWR configuration is defined in the dwr.xml file

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
    <dwr>
    <allow>
    <create creator="new" javascript="Service" scope="application">
    <param name="class" value="utils.Service" />
    </create>
    <convert converter="bean" match="utils.Data" />
    </allow>
    </dwr>

    WEB-INF/dwr.xml



    • "create" is used to define a Java object as being available to Javascript code.


    • The "javascript" attribute is the one that will be used in case of invoking the server-side methods from Javascript.


    • The converter definition allows utils.Data to be used as a parameter.






  8. Environment: This example was tested using DWR 2.0 RC 3, on Tomcat 5.5









[source]

1 comment: