Push Support

This example page explains how to push-enable a JSF Edition application through integration with the DWR server-side AJAX framework.

Prerequisites and Intended Audience

Software

The following software is required to build and deploy the example:

  • Backbase Enterprise Ajax 4.1.0 - JSF Edition (and higher)
  • DWR version 2.0.1
  • JDK 1.4.2 or above
  • Application server that supports Java Servlets 2.3 and JSP 2.0 specifications

Competencies

Experience to the indicated level is required with the following technologies:

  • Java beginner
  • JSF beginner

Resources

We will use the blank.war of the JSF Edition for this example. This is because the example relies on several resources that are outside the example scope.

Overview

AJAX Push Overview

AJAX dramatically increases web application usability and interactivity. However, getting a real-time feed of information from the server to the browser is an issue if the server can only respond to a browser request. The objective of push technologies is to overcome the problem by enabling servers to push content to browsers as soon as it is available. For more information, please see the Additional Resources.

Because a server cannot initiate contact with browsers, there are several techniques to implement the desired behavior:

  • Polling—the browser queries server repeatedly for content updates. Polling is the easiest to implement by adding a JavaScript function that that queries (polls) the server at regular intervals.
  • Comet—this technique requires that the connection between the client and server is never closed. Once the client has requested the web page, the server returns the data and tries to maintain an open connection for as long as possible. Using this connection the server can send data to the browser, and the data can be handled client-side using JavaScript.
  • Piggyback—this technique relies on sending new data on top of an response to an unrelated client request. Updated server-side data is stored until the client makes a new request. Together with the response, the server adds all the stored updates.

Each technique has advantages and limitations. For example, although polling and comet provide a more responsive solution than piggyback, they produce more network traffic.

The different techniques used to push content to the browser in the context of an AJAX application are sometimes referred to as reverse AJAX.

DWR Overview

DWR is an open source server-side AJAX framework, meaning that it is a library for developing AJAX web applications with a Java backend. The DWR framework includes Java classes that generate JavaScript at run-time, and this generated JavaScript code can then be invoked from static JavaScript. Hence it allows RPC-style of communication between Java (server-side) and JavaScript (client-side). Using this technique, although the execution appears to happen on the browser, in reality the server is executing the code and DWR is marshalling the exchange of data.

DWR consists of two main parts:

  • A Java servlet that processes requests and sends responses back to the browser
  • JavaScript running in the browser that sends requests and updates the web page based on the response from the server

As of version 2.0, DWR supports reverse AJAX, dividing push calls into two categories:

  • active—the server passes information client-side independent of ant request: comet and polling techniques are examples.
  • inactive—the server responds to requests: the piggyback technique is an example.

Integrating the JSF Edition with DWR

Adding the DWR library

In order to use DWR, it is necessary to add the dwr.jar from DWR distribution to the classpath of the web application.

Creating the DWR configuration file

The dwr.xml file contains description of classes used for generation of JavaScript, for example:

<?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="jsf" javascript="UserBean">
            <param xmlns="http://www.w3.org/1999/xhtml" name="managedBeanName" value="user" />
            <param xmlns="http://www.w3.org/1999/xhtml" name="class" value="com.backbase.push.UserBean" />
        </create>
        <convert converter="bean" match="com.backbase.push.Message"></convert>
    </allow>
</dwr>
       

Listing: the dwr.xml JSF extension point definition.

In the listing, the jsf creator is defined, which is the DWR extension point for JSF. This allows DWR to make calls to the ManagedBean.

The class parameter of the creator contains class name of the JavaBean which will be exposed by DWR as JavaScript. As a result, DWR will generate JavaScript at runtime which can be found under the following path:

<script src="/[CONTEXT-PATH]/dwr/interface/[SCRIPT-NAME].js"></script>
       

where [CONTEXT-PATH] is the context path of your web-application and [SCRIPT-NAME] is the name of JavaScript generated by DWR on base of the JavaBean (the name is defined in the javascript attribute of the creator element).

Changes to web deployment descriptor

Two additions to web.xml are needed to integrate the JSF Edition with DWR:

  • A DWR servlet definition is required to process DWR requests
  • A JSF integration filter definition is required to use the the jsf creator

Examples of these definitions are shown in the following listing:

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  ...
  <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>activeReverseAjaxEnabled</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>initApplicationScopeCreatorsAtStartup</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>maxWaitAfterWrite</param-name>
      <param-value>500</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>
  ...
  <filter>
    <filter-name>DwrFacesFilter</filter-name>
    <filter-class>org.directwebremoting.faces.FacesExtensionFilter</filter-class>
  </filter>
  ..
  <filter-mapping>
    <filter-name>DwrFacesFilter</filter-name>
    <url-pattern>/dwr/*</url-pattern>
  </filter-mapping>
  ..
</web-app>
       

Listing: web.xml settings required to integrate DWR with the JSF Edition.

The following initialization parameters are used to configure the DWR servlet:

  • debug—used at development time to provide detailed information about the JavaScript code generated by DWR (it is recommended to switch it to false in production mode)
  • activeReverseAjaxEnabled—setting this parameter to true sets the reverse AJAX mechanism to active, whereas false sets the mechanism to inactive.
  • initApplicationScopeCreatorsAtStartup—used to create application scope beans (defined in dwr.xml) at startup
  • maxWaitAfterWrite—the time to close the stream to allow data to be flushed to the registered clients.
  • load-on-startup—a value of 1 configures the servlet to be loaded on startup.

Add beans to the MyFaces configuration file

Add the Java classes to faces-config.xml as shown in the listing:

<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
 "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
 "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
    <managed-bean>
        <managed-bean-name>channelManager</managed-bean-name>
        <managed-bean-class>com.backbase.push.ChannelManagerBean</managed-bean-class>
        <managed-bean-scope>application</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>user</managed-bean-name>
        <managed-bean-class>com.backbase.push.UserBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
        <managed-property>
            <property-name>channelManager</property-name>
            <value>#{channelManager}</value>
        </managed-property>
    </managed-bean>
</faces-config>
       

Listing: faces-config.xml settings required to integrate DWR with the JSF Edition.

The channelManager bean is added as a dependency of the user bean.

Changes on a web-page

For a web page to work with reverse AJAX, the following change is required:

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

Listing: the onload setting for a web page to work with reverse AJAX.

The DWR dwr/engine.js, dwr/util.js, and the JavaScript auto-generated by DWR (dwr/interface/UserBean.js in our case) also need to be defined, as follows:

<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/UserBean.js"></script>
<script type="text/javascript" src="js/dwr.js"></script>

Listing: script tags for a web page to work with reverse AJAX.

In the snippet above you can find js/dwr.js also included which is a project specific JavaScript.

Live Demo

This examples page has demonstrated how the JSF Edition integrates with other server-side AJAX frameworks. The following figure shows a screen capture of the chat live demo:

Custom component design - click to view full-size

Figure: screen capture of a DWR chat session between two clients.

In the following live demo, the functionality implemented in the preceding steps is shown:

Additional Resources

For more information, please refer to the following documentation, examples and reference material: