CreateReverseAjaxWebAppsWithDWR

Create reverse Ajax Web-Applications with DWR, GlassFish and NetBeans 6.1

netbeans logo Direct Web Remoting glassfish

Written by Siegfried Bolz
The original blog is available at Another Random Developer Blog
If you have comments, suggestions.. feel free to drop a line in my blog.



In this tutorial you can read how to create a (very simple) reverse Ajax Web-Application, using NetBeans 6.1 BETA and running on GlassFish v2. This example is also working with previous NetBeans versions and Apache Tomcat 6.


Note:
Download-links to all files are available at the end of this blog-entry.


[[{TableOfContentsTitle=TableOfContents} | {TableOfContents title='Table of Contents'}]]

Prerequisites

To work with this example you need an installed NetBeans 6.1 (as above mentioned, older versions are working too) with included GlassFish v2 and the DWR-Jar’s (included in the Example-archive). If you don’t want to create this example from scratch, you can open it with NetBeans and run it immediately. You can read in my other blog Open existing projects in NetBeans 6 how to open an existing NetBeans project.


Introduction

There are many reverse Ajax Frameworks like COMETd and Pushlets which have the ability to push data from the Web Server to the Client (Browser). This effect is similar to applications using traditional Ajax with polling to detect new information on the server.
DWR, or Direct Web Remoting, is a Java open source library which helps developers write web sites that include Ajax technology. It allows code in a web browser to use Java functions running on a web server as if those functions were within the browser.

DWR Overview

DWR consists of two main parts:

  • A Java Servlet running on the server that processes requests and sends responses back to the browser.
  • JavaScript running in the browser that sends requests and can dynamically update the webpage.


Inspired by the Stocks-example from the Pushlets Project, i have created this example with the DWR-Technology. Once activated (this happens by clicking the button “Get Stocks”), this application is pushing stock rates to all opened browsers (which have a valid session).

Create the Project

First, launch NetBeans 6.1 BETA and enjoy the faster startup. NetBeans rulez
For all new features visit http://www.netbeans.org/community/releases/61/

launch NetBeans


Create a new Web Application project:
new project


Fill out the project-properties like this:
project properties


Click finish and you should see something like this:
fresh project


Now you have to add the required Jar-files (which are included in the example-archive). Rightclick on the project-name and choose Properties:
open project properties


Navigate to Libraries and add the Jar-files:
add jar files


In this example the Jar-files are located in the subdirectory /lib :
location of the jar-files



Add needed files

In the NetBeans-IDE, navigate to the file index.jsp and exchange the content with this JSP-code:

<%-- 
    Document   : index
    Created on : 06.04.2008, 15:39:59
    Author     : Siegfried Bolz
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
        <title>DWR StocksDemo</title>
        <META NAME="Copyright" CONTENT="Siegfried Bolz - http://blog.jdevelop.eu">
        
        <%-- This files are created in the runtime --%>
        <script type='text/javascript' src='/stocksdemo/dwr/util.js'></script>        
        <script type='text/javascript' src='/stocksdemo/dwr/interface/StocksDemo.js'></script>
        <script type='text/javascript' src='/stocksdemo/dwr/engine.js'></script>
        
        
        <script type="text/javascript">
            function getStocks() {
                StocksDemo.sendStocks();
            }
        </script>        
        
        <link rel="stylesheet" type="text/css" href="generic.css" /> 
    </head>
    
    <body onload="dwr.engine.setActiveReverseAjax(true);">
        
        <div id="page-title">[
            <a target="_blank" href="http://blog.jdevelop.eu">Another Random Developer Blog</a> |
            <a target="_blank" href="dwr/index.html">DWR API Overview</a> |
            <a target="_blank" href="http://getahead.org/dwr">Getahead.org</a>
        ]</div>
        
        <h1>Receiving Stock Rates using Reverse Ajax</h1>
        
        <p>The following example illustrates how stock rates can be pushed from the server. Note: these are faked rates. A real application would use something like a Reuters live stockfeed at the back-end.</p>
        <input type="button" value="Get Stocks" onclick="getStocks()"/>
        <hr>
        
        <table style="width:500px" border="0" cellpadding="0">
            <tr>
                <td class="headName" ><b>Name</b></td>
                <td class="headValue" ><b>value</b></td>
            </tr>
            <tr><td>Allianz SE</td><td><div id="allianz">wait...</div></td></tr>
            <tr><td>Bayer AG</td><td><div id="bayer">wait...</div></td></tr>
            <tr><td>BMW AG St</td><td><div id="bmw">wait...</div></td></tr>
            <tr><td>Commerzbank AG</td><td><div id="commerzbank">wait...</div></td></tr>
            <tr><td>Daimler AG</td><td><div id="daimler">wait...</div></td></tr>
            <tr><td>Deutsche Bank AG</td><td><div id="deutschebank">wait...</div></td></tr>
            <tr><td>Deutsche Post AG</td><td><div id="deutschepost">wait...</div></td></tr>
            <tr><td>Deutsche Telekom AG</td><td><div id="telekom">wait...</div></td></tr>
            <tr><td>Hypo Real Estate Holding AG</td><td><div id="hypo">wait...</div></td></tr>
            <tr><td>Infineon Technologies AG</td><td><div id="infineon">wait...</div></td></tr>
            <tr><td>Linde AG</td><td><div id="linde">wait...</div></td></tr>
            <tr><td>METRO AG St</td><td><div id="metro">wait...</div></td></tr>
            <tr><td>RWE AG St</td><td><div id="rwe">wait...</div></td></tr>
            <tr><td>SAP AG</td><td><div id="sap">wait...</div></td></tr>
            <tr><td>Siemens AG</td><td><div id="siemens">wait...</div></td></tr>
            <tr><td>TUI AG</td><td><div id="tui">wait...</div></td></tr>
            <tr><td>Volkswagen AG St</td><td><div id="vw">wait...</div></td></tr> 
        </table>  
        
        <br>
        
        <div id="page-footer">Copyright 2008 by <a href="http://blog.jdevelop.eu" target="_blank">Siegfried Bolz</a></div>
    </body>
</html> 


index.jsp


You are wondering where the JavaScript-files located? They are generated during runtime from the DWR Jar-files. This is the reason why NetBeans shows some errors. Ignore them!


Create the stylesheet-file generic.css with this code:

@CHARSET "ISO-8859-1";

body { margin:60px 40px 0px 40px; color:#666; line-height:1.3em;
  font-family:'Century Gothic', Helvetica, Arial, clean, sans-serif;
}

select, textarea, input[[Type=text | type='text']], input[Type=password] {
  font-family:'Century Gothic', Helvetica, Arial, clean, sans-serif;
  font-size:1em; padding:3px 3px; margin:2px; border:1px solid #999;
}

button, input[[Type=button | type='button']], input[[Type=submit | type='submit']], input[Type=cancel] {
  font-family:'Century Gothic', Helvetica, Arial, clean, sans-serif;
  font-size:1em;
}

a { color:Blue; text-decoration:none; }
a:hover { background-color:#ffc; color:#fc6; }
a:active { color:#fc6; }

h1 { color:#000; font-weight:bold; font-size:130%; }
h2 { color:#000; font-size:110%; }
h3 { color:#000; font-size:100%; }
h4 { color:#000; font-size:90%; }

img { border:0; }

table { border-collapse:collapse; border-spacing:5px; }
table, td, th { border:1px solid #ccc; padding:5px; }
table.form th { text-align:right; font-weight:normal; }
table.grey th { background:#eee; font-weight:normal; }
table.plain { border:0; }
table.plain td { border:0; }
table.plain th { border:0; }


#page-title { background-color:#7272a2; border:1px solid #000000;
  border-top:0; padding:5px; font-size:80%; line-height:1.8em;
  position:absolute; top:0; left:0; width:100%; color:#ccc;
}
#page-title a { text-decoration:none; color:white; }
#page-title a:hover { background-color:#7272a2; color:#ff3; }
#page-title a:active { color:#fc6; }

#page-footer { background-color:#7272a2; border:1px solid #000000;
  border-top:0; padding:5px; font-size:80%; line-height:1.8em;
  position:absolute;left:0;width:100%;color:#ccc;
}

#page-footer a { text-decoration:none; color:white; }
#page-footer a:hover { background-color:#7272a2; color:#ff3; }
#page-footer a:active { color:#fc6; }

#headName { width:300px;} 



Open the file web.xml and insert this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <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>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>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app> 



web.xml


Now create the file dwr.xml, located in the directory /WEB-INF :

create new xml file



choose xml document



finish it



Insert this in dwr.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
"http://getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
    <allow>
        <create creator="new" javascript="StocksDemo">
            <param name="class" value="eu.jdevelop.dwrstocksdemo.StocksDemo"/>
        </create>
    </allow>
</dwr>



dwr.xml



Create the java class file StocksDemo:

StocksDemo.java

and insert this:

package eu.jdevelop.dwrstocksdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.dwr.Util;
import org.directwebremoting.util.Logger;
 
/**
 * Reverse Ajax class.
 * 
 * @author Siegfried Bolz (blog.jdevelop.eu)
 */
public class StocksDemo {
 
    protected static final Logger log = Logger.getLogger(StocksDemo.class);
       
    private List<StocksBean> stocks = new ArrayList<StocksBean>();

    
    /**
     * Initialize the stocklist with values.
     */
    public StocksDemo() {
        stocks.add(new StocksBean("bmw", "36.55"));
        stocks.add(new StocksBean("linde", "91.01"));
        stocks.add(new StocksBean("commerzbank", "22.59"));
        stocks.add(new StocksBean("infineon", "5.07"));
        stocks.add(new StocksBean("siemens", "71.77"));
        stocks.add(new StocksBean("sap", "31.61"));
        stocks.add(new StocksBean("bayer", "51.29"));
        stocks.add(new StocksBean("metro", "52.70"));
        stocks.add(new StocksBean("tui", "16.96"));
        stocks.add(new StocksBean("daimler", "54.34"));
        stocks.add(new StocksBean("vw", "178.48"));
        stocks.add(new StocksBean("allianz", "134.48"));
        stocks.add(new StocksBean("deutschebank", "76.32"));
        stocks.add(new StocksBean("rwe", "80.63"));
        stocks.add(new StocksBean("hypo", "18.79"));
        stocks.add(new StocksBean("deutschepost", "20.19"));
        stocks.add(new StocksBean("telekom", "11.13"));
    }

    
    /**
     * Send the Stock-Values to the file "index.jsp"
     */
    public void sendStocks() throws InterruptedException {
        WebContext wctx = WebContextFactory.get();
        String currentPage = wctx.getCurrentPage();

        Collection sessions = wctx.getScriptSessionsByPage(currentPage);
        Util utilAll = new Util(sessions);
  
        for (int i = 0; i < stocks.size(); i++) {
            Thread.sleep(1000);
            utilAll.setValue(stocks.get(i).getStock(), stocks.get(i).getValue());
            log.info("Pushing stock: " + stocks.get(i).getStock() + " = " + stocks.get(i).getValue());
        }

    }

} // .EOF 


Create the class StocksBean with the same package and insert this code:

StocksDemo.java

package eu.jdevelop.dwrstocksdemo;

/**
 * This bean is used for storing one stock rate.
 * 
 * @author Siegfried Bolz
 */
public class StocksBean {

    private String stock = "";
    private String value = "";

    public StocksBean(String stock, String value) {
        this.setStock(stock);
        this.setValue(value);
    }

    public String getStock() {
        return stock;
    }

    public void setStock(String stock) {
        this.stock = stock;
    }

    public String getValue() {
        return value;
    }

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



The last file, create it in the source-directory:

log4j.properties

log4j.rootLogger=INFO, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x -%m%n



log4j.properties



Alright, the job is done. Your NetBeans-project just have to look like this:
finished project



Testing

Build, deploy and launch the project. Browse to the URL http://localhost:8080/stocksdemo. You see the simple StocksDemo-Web Application. Open more browser-windows with the same URL. Click in one of them on the button Get Stocks to activate the reverse Ajax. In short time distances you can see how the values in all opened browser-windows are filled with the same numbers. This happens because DWR stores all active sessions in the memory:


Collection sessions = wctx.getScriptSessionsByPage(currentPage); 
Util utilAll = new Util(sessions);



running in browser



You can see the current pushed stock-value in the NetBeans output-console:
netbeans console output



Flash-video

I have made a Flash-video where you can see this application in action: Watch Flash Video



Deploy WAR manually to GlassFish

Note:
If you don’t know how to work with GlassFish, read the first two chapters at Installing GlassFish v2 with PHP5 on Port 80


Login to the GlassFish Admin Console and navigate on the left side to Applications->Web Applications.

GlassFish admin console



Hit deploy and upload the file dwrstocksdemo.war.

deploy war archive



After uploading the WAR-file, you can launch the application directly from the Admin Console. If you see nothing in your browser, be sure that your URL is using the correct port (standard: 8080).



launch deployed application



Possible Problem

I encountered an obscure problem with the Internet Explorer 7. There are no JavaScript errors or something else, but the Get Stocks-button does not work. With Firefox, Opera and Konqueror everything is working fine. Does someone else have the same problem (or not) ?



Downloads

  1. NetBeans 6.1 BETA Project: download
  2. WAR-File (ready for deployment): download



Have a lot of fun!

---
Siegfried Bolz
Another Random Developer Blog

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo