Technologies that are relevant to Web 2.0, such as Asynchronous JavaScript™ XML (Ajax), Web remoting, Web messaging, and others, have become increasingly prevalent in today’s Web applications. Compared with traditional Web applications, Ajax-based applications make it possible to provide much more responsiveness and interactivity. In those Web applications incorporating Ajax architecture, users don’t need to wait for the entire Web page to be reloaded before seeing new results from the server, and they can often complete tasks with fewer steps on a single Web page that is presented in an incremental or on-demand fashion.
To address the growing need for rapid development and delivery of Ajax-enabled solutions, the IBM WebSphere Application Server Feature Pack for Web 2.0 provides a rich set of components that enables you to build Ajax-based applications easily and efficiently. It also provides an open standards-based framework for integrating existing services or solution assets into rich Internet applications.
The major components of the feature pack include:
- Ajax client/proxy runtime
- RPC (Remote Procedure Call) adapter
- Web messaging service
- JSON4J (JavaScript Object Notation for Java) library
- IBM SOAP library
- IBM Atom library
- IBM OpenSearch library
- IBM Gauge widget.
This article describes the steps for building an Ajax-based chart application using the Web 2.0 feature pack. By following this example, you will be able to see how the components included in the feature pack can be used together to construct a complete Web 2.0 solution with a rich user experience.
This exercise assumes a fundamental knowledge of Web application development and familiarity with Eclipse or IBM Rational® Application Developer. To follow these steps, you will need to have the WebSphere Application Server Feature Pack for Web 2.0 installed successfully in a properly operating WebSphere Application Server (V6.0, 6.1 or 7.0) environment.
About the sample dynamic application
The sample application included with this article is intended to demonstrate possible ways you can use the major components of the Web 2.0 feature pack to build an Ajax-based application while still being able to address changing business requirements. This sample application uses dynamic charts to report the sales quantities of automobile brands within a give time period (in a bar chart), and also lets users select a specific brand to view the sales distribution by area (in pie chart). Further, when the back-end data changes, the updated data is automatically presented to users in these charts.
The sample application, DynamicCharts, has these features:
- Provides a chart view for car sales of multiple automobile brands.
- Provides a chart view for drilling down to sales distribution by region for a specific brand.
- Updates charts displayed in a Web browser automatically at a configurable interval (initially 15 seconds).
- Provides a flexible layout that enables users to adjust the size of both the master view and the detail view.
The DynamicCharts application is built with these feature pack facilities:
- Ajax client runtime
- RPC adapter
- Web messaging service
- JSON4J.
Figure 1 illustrates the major functions of the DynamicCharts application, and Figure 2 depicts the application's overall structure and flow.
Figure 1. Functions of DynamicCharts example
Figure 2. Overall structure and flow of DynamicCharts example
In Figure 2, you can see that the client logic implemented by the Ajax client runtime:
- Retrieves the data from the facade interface of the chart data service -- which could be an existing service or solution asset -- and is exposed by the RPC adapter.
- Creates or updates the charts.
- Handles the events triggered by users and by the Web messaging service.
The invocations from client to RPC adapter are all based on JSON RPC, and the returned data is encapsulated in JSON objects, which can be parsed on the client side very quickly. The chart data updater simulates other applications or services that will update the chart data under certain circumstances, publishing the data change event to clients through the WebSphere Application Server Service Integration Bus (SIBus) and the Web messaging service. Both the chart data service and the chart data updater depend on the chart data accessor to load data from or store data to a data store. (For the purpose of this article, the chart data accessor in the sample application does not connect to an actual data store.)
The next sections will walk you through the process to create the DynamicCharts application. The major steps involved will be to:
- Import essential components
- Create the chart application using the Dojo Toolkit
- Expose ChartService to JavaScript clients via the RPC adapter
- Publish data updates to the Web browser with Web messaging
The entire sample application, including WAR and source files, and included with this article for you to download and deploy.
- Create a Dynamic Web Project and EAR named "DynamicCharts"
in your development environment (meaning Eclipse or Rational Application
Developer). Figure 3 shows the project directory structure.
Figure 3. DynamicCharts project directory structure
- If you are using Eclipse, import the Ajax client runtime and utility JARs to the WebContent folder.
- Implement a set of Java™ classes in the dataservice package.
- Create the dynamic-chars.html page.
If you’re using Rational Application Developer V7.5 or later, then you don’t have to explicitly import the Ajax client runtime and Web 2.0 utility JARs, because they will be available in your project when you enable Web 2.0 in Project Faces.
If you’re using Eclipse to create this sample application, a few more steps will be needed:
- Copy the ajax-rt_1.X folder from the Web 2.0 feature pack
installation root directory (usually
<app_server_root>/web2fep) to the WebContent folder of
your newly created project (Figure 4).
Figure 4. Ajax client runtime
- Locate these five JAR files under the optionalLibraries folder in
the Web 2.0 feature pack installation root directory and copy them to
the WebContent/WEB-INF/lib folder of your project (Figure 5):
- commons-logging-1.0.4.jar
- RPCAdapter.jar
- RPCAdapter-annotation.jar
- retroweaver-rt-2.0.jar
- webmsg_applib.ja
Figure 5. Web 2.0 utility JARs
When the required libraries have been imported into your project, you can begin with your application code.
Create the chart application using the Dojo Toolkit
The Dojo Toolkit is a powerful, flexible, modular, open source Ajax software development kit that enables you to easily build dynamic capability into Web pages. The Web 2.0 feature pack incorporates Dojo Toolkit 1.1 and IBM extensions, such as the Ajax client runtime. In this section, you will see how easy it is to use the Dojo Toolkit to implement a chart page that has user interactions and back-end services.
- Create an HTML page and load the base Dojo script
(ajax-rt_1.X/dojo/dojo.js) with the
<script/>tag in the head section. This provides the core functions of Dojo and as well as the access to all other Dojo facilities. - Import the Dojo styles within the
<style/>tag and declare the Dojo packages that will be referred to on this Web page withdojo.require(…), as shown in Listing 1.
Listing 1. Declaring Dojo components and themes<style type="text/css"> @import "ajax-rt_1.X/dojo/resource/dojo.css"; @import "ajax-rt_1.X/dijit/themes/tundra/tundra.css"; @import "dynamic-charts.css"; </style> <script type="text/javascript" src="ajax-rt_1.X/dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true, usePlainJson: true"></script> <script type="text/javascript"> dojo.require("dojox.charting.Chart2D"); dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("dojo.rpc.JsonService"); dojo.require("dojox.cometd"); dojo.require("dojox.charting.themes.PlotKit.orange"); </script>
- After that, define the page layout in the body section of the HTML
file (Listing 2):
- The Dojo layout widget
dijit.layout.BorderContaineris used here for the page layout, split into twodijit.layout.ContentPanes, one for the car sale chart and the other for the distribution chart. - The
splitterattribute of the seconddijit.layout.ContentPaneis set to true, which enables the user to change and adjust the widths of those two regions. - In each region, one or two
<div>tags are embedded as the nodes where you will create a chart or radio button group.
Be aware that the original dijit.layout.SplitContainer has been deprecated in Dojo 1.1 and that dijit.layout.BorderContainer is introduced as a replacement.
Listing 2. Defining the chart page layout<div dojoType="dijit.layout.BorderContainer" design="sidebar" id="main"> <div dojoType="dijit.layout.ContentPane" region="center" id="sale_pane"> <p>Car Sale</p> <div id="car_sale_chart"></div> </div> <div dojoType="dijit.layout.ContentPane" region="trailing" splitter="true" id="distribution_pane"> <p>Choose a brand to view sale distribution by area</p> <div id="brand_picker"></div> <div id="distribution_by_area"></div> </div> </div>
- The Dojo layout widget
- You are now ready to work out the JavaScript code. The JavaScript
functions to be implemented are summarized in this table:
Function Trigger function/event Task description init() Page onload event Call getSaleData() and register Web messaging handler webmsgHandler(…) Web messaging service Process event triggered by Web messaging service getSaleData() init() Register JSON RPC handler and loading sale data showCarSale(…) getSaleData() Parse returned sale data and call functions to make charts makeSaleChart(…) showCarSale() Create sale chart makeBrandPicker(…) showCarSale() Create brand radio group and register onclick handler brandPickerHander() User’s action Identify selected brand and call functions to make charts getDistributionData(…) brandPickerHander() Register JSON RPC handler and loading distribution data makeDistributionChart(…) getDistributionData(…) Create distribution chart
Next, you need to load and parse the car sales data from the back-end service. The JavaScript fragment in Listing 3 illustrates how to invoke the chart data service through the JSON RPC call and RPC adapter. You just need to create a Dojo JSON service instance with the given URL exposed by RPC adapter.
The first parameter:
/DynamicCharts/RPCAdapter/jsonrpc/ChartDataService/getCarSale
means to call the getCarSale() method of the ChartDataService class (this will be explained more later) and then register the callback function showCarSale(...) to the JSON service instance, where the returned JSON-formatted data is parsed, and the brand and quantity data are put to arrays respectively.
There is another option to perform a JSON RPC call -- using the Dojo XMLHTTPRequest wrapper (dojo.xhr) -- but that requires more coding and is not as straightforward as what is shown in Listing 3.
Listing 3. Loading and parsing of the car sale data// Retrieve the sale data via JSON RPC invocation and make // the charts. function getSaleData() { // Call the json service to retrieve the car sale data var json_svc = new dojo.rpc.JsonService( "/DynamicCharts/RPCAdapter/jsonrpc/ChartDataService/getCarSale"); json_svc.getCarSale().addCallback(showCarSale); } // Parse the sale data and create the sale chart and the brand picker // function showChart(data, ioArgs) { function showCarSale(sale_data) { // Parse the data returned from the server var sale_brands = new Array(); var sale_quantities = new Array(); for (var i=0;i<sale_data.length;i++) { sale_brands[i] = {value:(i+1), text:sale_data[i].brand}; sale_quantities[i] = sale_data[i].quantity; } // Make the auto sale chart makeSaleChart(sale_brands, sale_quantities); // Make the brand picker makeBrandPicker(sale_brands); }
- Once the chart date is loaded and parsed, the makeSaleChart
function will be invoked to create the sales chart (Listing 4). The
Dojo Chart2D object usually consists of four parts: theme, plot, axis
and series (data). The addPlot call determines what types of charts
you’re going to produce. There are a variety of plot types available.
The most commonly used are lines, bars, columns, areas, grid, markers,
pie, stacked, and so on. Here, "Columns" is used as the vertical bar
chart for the car sales. Both addPlot and addAxis functions take two
parameters: a name and an argument array. The addSeries function
accepts additional parameter: an array of data series.
Listing 4. Creating the car sales chart// Create the sale chart function makeSaleChart(brands, quantities) { if (sale_chart == undefined) { // Make the sale chart for the first request of a given user sale_chart = new dojox.charting.Chart2D("car_sale_chart"); sale_chart.setTheme(dojox.charting.themes.PlotKit.orange); sale_chart.addPlot("default", {type:"Columns", gap:2}); sale_chart.addAxis("x", {labels:brands}); sale_chart.addAxis("y", {vertical:true, includeZero:true, max:50}); sale_chart.addSeries("Auto Sale", quantities, {stroke:{color:"black"}, fill:"lightblue"}); sale_chart.render(); } else { // Update the sale chart sale_chart.updateSeries("Auto Sale", quantities); sale_chart.render(); } }
The brand picker radio group is created in Listing 5, based on the returned brands while making the sales chart above.
Listing 5. Creating the brand picker// Create the brand picker function makeBrandPicker(brands) { var picker = dojo.byId("brand_picker"); var pickerNode = dojo.byId("picker_node"); if (pickerNode == undefined) { pickerNode = document.createElement("div"); dojo.attr(pickerNode, "id", "picker_node"); for (var i=0;i<brands.length;i++) { var option; // Different code for IE and FF respectively if (dojo.isIE) { option = document.createElement("<input name='auto_brand'>"); } else { option = document.createElement("input"); dojo.attr(option, "name", "auto_brand"); } // Create the radio option dojo.attr(option, "type", "radio"); dojo.attr(option, "id", brands[i].text); dojo.attr(option, "value", brands[i].text); dojo.attr(option, "dojoType", "dijit.form.RadioButton"); // connect onclick to the picker handler dojo.connect(option, "onclick", brandPickerHandler); pickerNode.appendChild(option); // Create the label var lbl = document.createElement("label"); dojo.attr(lbl, "for", brands[i].text); var txt = document.createTextNode(brands[i].text); lbl.appendChild(txt); pickerNode.appendChild(lbl) var nl = document.createElement("br"); pickerNode.appendChild(nl); } picker.appendChild(pickerNode); } else { // if the picker node exists, just refresh the selection brandPickerHandler(); } }
There are only general HTML DOM (Document Object Model) operations in the makeBrandPicker function. The only thing to be aware of is whether the brandPickerHander function is registered as the onclick handler using dojo.connect, which will locate the user selected brand and trigger the creation or update of the distribution chart, as shown in Listing 6.
Listing 6. Processing brand selection event// Brand picker event handler function brandPickerHandler() { // Find out the selected brand var pickerNode = dojo.byId("picker_node"); var children = pickerNode.childNodes; var selected_brand; for (var i=0;i<children.length;i++) { if (children[i].checked != undefined && children[i].checked == true) { selected_brand = children[i].value; // Retrieve the updated distribution data and refresh the distribution // chart based on the selected brand getDistributionData(selected_brand); break; } } }
- The loading of the distribution data and the creation of the
distribution chart are similar to those of the sales data and chart,
except that the plot type Pie is used, as shown in Listing 7.
Listing 7. Loading the distribution data and creating the distribution chart// Retrieve the distribution data via JSON RPC invocation and // make the distribution chart. function getDistributionData(brand) { // Call the json service to retrieve the distribution data var json_svc = new dojo.rpc.JsonService( "/DynamicCharts/RPCAdapter/jsonrpc/ChartDataService/getDistributionByArea"); json_svc.getDistributionByArea(brand).addCallback(makeDistritubtionChart); } // Create the distribution chart function makeDistritubtionChart(dist_data) { // Parse the distribution data var dist_percentage = new Array(); for (var i=0;i<dist_data.length;i++) { var data = dist_data[i] dist_percentage[i] = { y:data.percent,text:data.region+"("+Math.round(data.percent)+"%)", color:data.color}; } if (dist_chart == undefined) { // Make the distribution chart for the first request of a given user dist_chart = new dojox.charting.Chart2D("distribution_by_area"); dist_chart.setTheme(dojox.charting.themes.PlotKit.orange); dist_chart.addPlot("default", {type:"Pie",font:"normal normal bold 6pt sans-serif",fontColor:"white"}); dist_chart.addSeries("Area Distribution", dist_percentage); dist_chart.render(); } else { // Update the distribution chart dist_chart.updateSeries("Area Distribution", dist_percentage); dist_chart.render(); } } - The last part of the JavaScript implementation is to define the
init function that will be called right after the page load. This
function takes care of the global initialization, such as initializing
the Web messaging servlet, registering the Web messaging handler, and
subscribing the /charttopic topic, as well as calling other functions
to load the sales data. (More on Web messaging in the next sections.)
Listing 8. Initializing the Web messaging handler// Web Messaging handler. function webmsgHandler(msg) { if (msg.data == "UPD") { // Get the updated sale data from the backend getSaleData(); } } // Perform initialization when loading the page. function init() { // Use the "tundra" style dojo.addClass(dojo.body(), "tundra"); // Get the sale data from the backend getSaleData(); // Initalize the web messaging client dojox.cometd.init("webmsgServlet"); dojox.cometd.subscribe("/charttopic", window, "webmsgHandler"); }
Expose ChartService to JavaScript clients via the RPC adapter
The RPC adapter (Web remoting) provides the ability for JavaScript or client-side code to directly invoke server-side logic via a JSON RPC call. That means that POJO methods can be easily invoked by Ajax applications without restructuring the existing implementations for lightweight clients.
Listing 9 shows the Java bean ChartData that will provide the chart data service exposed through the RPC adapter. Two methods are available in this Java class:
- getCarSale() for retrieving the sales data for all automobile brands.
- getDistributionByArea(...) for retrieving the distribution data for the selected brand through the chart data access component ChartDataAccessor.
Listing 9. Implementing the chart service
public class ChartData{
private static final Logger logger = Logger.getLogger("dataservice.ChartData");
/**
* Gets the sale data of all auto brands
* @return sale data for all brands
*/
public CarSale[] getCarSale() {
// Retrieve the sale data with the chart DAO.
logger.log(Level.INFO, "Retrieving car sale data for all brands.");
return ChartDataAccessor.getInstance().loadSaleData();
}
/**
* Gets the distribution data by area for a given auto brand.
* @param brand
* @return distribution data for the given brand
*/
public AreaDistribution[] getDistributionByArea(String brand) {
// Retrieve the distribution data with the chart DAO.
logger.log(Level.INFO, "Retrieving distribution data for " + brand + ".");
return ChartDataAccessor.getInstance().loadDistributionDataByBrand(brand);
}
} |
To publish these methods to Ajax clients, you need to create the RpcAdapterConfig.xml configuration file in the WebContent/Web-INF folder in the project:
- If using Rational Application Developer V7.5, navigate to Project => Services => Expose RPC Adapter Service and you won’t need to manually create the configuration file. Specify <default-format /> to JSON because you want the returned data in JSON format to be processed by JavaScript directly and quickly.
- Set the service name and implementation to
ChartDataServiceanddataservice.ChartDatarespectively, and expose the two methods getCarSale() and getDistributionByArea() in <methods />.In addition to defining the exposed methods in RpcAdapterConfig.xml, there is another way to expose the RPC adapter service by having the ChartData class implement the com.ibm.webphere.rpcadapter.SelfBeanInfo interface, and provide the information of exposed methods in the getBeanDescriptorInfo() method.
Listing 10. Publishing the chart service in RpcAdapterConfig.xml<?xml version="1.0" encoding="UTF-8"?> <rpcAdapter xmlns="http://www.ibm.com/xmlns/prod/websphere/featurepack/v6.1/RpcAdapterConfig" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <default-format>json</default-format> <services> <pojo> <name>ChartDataService</name> <implementation>dataservice.ChartData</implementation> <description>The facade for the chart data service.</description> <methods> <method> <name>getCarSale</name> <description>Gets all the car sale data.</description> <http-method>GET</http-method> </method> <method> <name>getDistributionByArea</name> <description>Gets the distribution data.</description> <http-method>GET</http-method> <parameters> <parameter> <name>brand</name> <description>a specific brand</description> </parameter> </parameters> </method> </methods> </pojo> </services> </rpcAdapter> - The last step for publishing the chart data service is to configure
the web.xml file so that the
com.ibm.websphere.rpcadapter.RPCAdapter servlet is exposed under this Web
address:
http://<host>:<port>/DynamicCharts/RPCAdapter/*
To do this, add the servlet configuration in Listing 11 to the web.xml file.
Listing 11. Configuring RPC adapter Servlet in web.xml<servlet> <display-name>RPCAdapter</display-name> <servlet-name>RPCAdapter</servlet-name> <servlet-class>com.ibm.websphere.rpcadapter.RPCAdapter</servlet-class> </servlet> <servlet-mapping> <servlet-name>RPCAdapter</servlet-name> <url-pattern>/RPCAdapter</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RPCAdapter</servlet-name> <url-pattern>/RPCAdapter/*</url-pattern> </servlet-mapping> - You can now test the chart service via RPC adapter. Open these URLs in
your Web browser and download the results:
http://<host>:<port>/DynamicCharts/RPCAdapter/httprpc/ChartDataService/getCarSale http://<host>:<port>/DynamicCharts/RPCAdapter/httprpc/ChartDataService/ getDistributionByArea?brand=BMW
Publish data updates to Web browsers with Web messaging
The Web messaging service connects a browser to the WebSphere Application Server SIBus for server-side event push via a publish/subscribe implementation, making it easy for you to build Web applications with real-time data updates, such as stock price quotes, auction bids, and automatic news updates.
Client/server communication is achieved through an HTTP-based message
routing protocol called the Bayeux protocol. Cometd is a Dojo Foundation
project to provide implementations of the Bayeux protocol in JavaScript
and other languages. The code in Listing 8 uses Dojo Cometd to initialize
the Web messaging servlet, subscribe the /charttopic topic, and register
the Web message handler at the client side. There is little code that
needs to be written for enabling the Web messaging service at the server
side, except for some configurations of Web messaging and SIBus. (The
deployment instructions in the next section explain how to set the
webmsgenabled parameter and create the chartbus SIBus on the application
server.
There is also a Web messaging configuration file webmsg.json in the
WebContent/WEB-INF of the DynamicCharts project (Listing 12). In this
file, busName is set to chartbus. For the purpose of this example,
clientCanPublish is set to false because the server-side publish is
sufficient here.
Listing 12. Configuring the Web messaging service in webmsg.json
{
"WebMsgServlet":
{
"busName": "chartbus",
"destination": "Default.Topic.Space",
"clientCanPublish": false,
"longPollTimeout": 30
}
} |
Let’s take a close look at the implementation of the chart data updater and how to publish a server event to clients with the JMS topic connection factory.
The ChartDataUpdater class implements the TimerListener interface CommonJ
Timer (see Resources). When the timer expires, the timerExpired method of
the ChartDataUpdater object will be run to simulate the chart data
updates by other solutions or services and then publish a message to Web
clients. To assist in publishing to Web messaging clients, a publishing
API is provided in the Web messaging application utility library. Listing
13 demonstrates usage of the publishing API; that is, publishing the
message UPD through the Bayeux channel /charttopic encapsulated in
BayeuxJmsTextMsg.
Listing 13. Implementing the timerExpired interface for the chart data updater
/**
* Perform the scheduled task at the given interval, implementing
* the interface of TimerListener.
*/
public void timerExpired(Timer timer) {
logger.log(Level.INFO, "Entering timer listener.");
try {
// Update the data
logger.log(Level.INFO, "Updating chart data.");
ChartDataAccessor cda = ChartDataAccessor.getInstance();
cda.storeSaleData(simulateSaleData());
cda.storeDistributionData(simulateDistributionData());
// Notify the clients of the chart data updates
logger.log(Level.INFO, "Notifying Web browser clients of data updates");
publisher.publish(new BayeuxJmsTextMsg("/charttopic", "UPD"));
} catch (PublisherException e) {
e.printStackTrace();
logger.log(Level.SEVERE, e.getMessage());
}
logger.log(Level.INFO, "Exiting timer listener.");
} |
The start, schedule, and stop of the chart data updater are done by calling TimerManager of CommonJ Timer (Listing 14).
Listing 14. Implementing the start/stop methods of the chart data updater
/**
* Starts the chart data updater.
*
*/
public void startUpdater() {
try {
if (!timerRunning) {
InitialContext ctx = new InitialContext();
tmgr = (TimerManager)ctx.lookup("java:comp/env/tm/default");
tmgr.schedule(this, 5, UPDATE_INTERVAL);
timerRunning = true;
logger.log(Level.INFO, "The chart data updater is started.");
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
logger.log(Level.SEVERE, e.getMessage());
} catch (IllegalStateException e) {
e.printStackTrace();
logger.log(Level.SEVERE, e.getMessage());
} catch (NamingException e) {
e.printStackTrace();
logger.log(Level.SEVERE, e.getMessage());
}
}
/**
* Stops the chart data updater.
*
*/
public void stopUpdater() {
if (timerRunning) {
if (tmgr != null) {
tmgr.stop();
logger.log(Level.INFO, "The chart data updater is stopped.");
}
}
} |
Additionally, you need to get the Publisher instance, initialize ChartDataUpdater with the publisher, and start ChartDataUpdater in the init method of the startup servlet. Furthermore, you need to shut down ChartDataUpdater in the servlet context listener when the servlet context is destroyed (Listing 15).
Listing 15. Implementing lifecycle management of the chart data updater
/* (non-Javadoc)
* @see javax.servlet.GenericServlet#init()
*/
public void init() throws ServletException {
// Call the init() of the super class
super.init();
// Get and initialize the instance of ChartDataUpdater (pass in the publisher)
ServletContext servletContext = getServletConfig().getServletContext();
Publisher publisher = (Publisher) servletContext.getAttribute(
JmsPublisherServlet.PUBLISHER_SERVLET_CONTEXT_KEY);
ChartDataUpdater cdu = new ChartDataUpdater(publisher);
cdu.startUpdater();
// Keep the chart data updater, and clean it up when the context is destroyed
servletContext.setAttribute(ChartDataUpdater.UPDATER_KEY, cdu);
}
/* (non-Java-doc)
* @see javax.servlet.ServletContextListener#contextDestroyed(ServletContextEvent arg0)
*/
public void contextDestroyed(ServletContextEvent arg0) {
// Stop the timer when context is destroyed
ChartDataUpdater cdu = (ChartDataUpdater) arg0.getServletContext()
.getAttribute(ChartDataUpdater.UPDATER_KEY);
if (cdu != null) {
cdu.stopUpdater();
}
} |
Finally, put in the servlet configurations for JMS Publisher and Web messaging, and the resource references for CommonJ Timer and the JMS Topic Connection Factory (Listing 16).
Listing 16. Configuring Web messaging in web.xml
<servlet>
<description></description>
<display-name>Publisher</display-name>
<servlet-name>Publisher</servlet-name>
<servlet-class>
com.ibm.websphere.webmsg.publisher.jndijms.JmsPublisherServlet
</servlet-class>
<init-param>
<description></description>
<param-name>CONNECTION_FACTORY_JNDI_NAME</param-name>
<param-value>java:comp/env/jms/ChartPublish</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<description/>
<display-name>WebMsgServlet</display-name>
<servlet-name>WebMsgServlet</servlet-name>
<servlet-class>com.ibm.websphere.webmsg.servlet.WebMsgServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WebMsgServlet</servlet-name>
<url-pattern>/webmsgServlet</url-pattern>
</servlet-mapping>
<resource-ref id="ResourceRef_1224495798546">
<description></description>
<res-ref-name>tm/default</res-ref-name>
<res-type>commonj.timers.TimerManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
<resource-ref id="ResourceRef_1224558884500">
<description></description>
<res-ref-name>jms/ChartPublish</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref> |
You have completed the development of the DynamicCharts sample. The next section explains how you can export the entire WAR file, and how to deploy and run this example.
Download and deploy the example
The DynamicCharts WAR file, including the source code, is provided with this article for download. These files have been verified on both Internet Explorer and Firefox with WebSphere Application Server V6.1.0.13 with PK56881. You must be sure to import all the dependent JAR files and the Ajax runtime prior to deployment.
To install the DynamicCharts example:
- Verify that the WebSphere Application Server Feature Pack for Web 2.0 is installed and operating properly.
- Enable the Web messaging service:
- Log onto the WebSphere Application Server administrative console and navigate to Servers => Application servers. Select the server to which DynamicChartsEAR.ear will be deployed.
- Expand Web Container Settings, select Web container transport chains, and then select the WCInBoundDefault transport chain.
- Select Web container inbound channel and then select Customer Properties.
- Click New and enter
webmsgenabledfor the name property and true for the value. - Click Apply and then Save to save the repository information.
- Restart the application server.
- Create and configure the chartbus SIBus:
- Log on to the admin console and navigate to Service integration => Buses.
- Click New and enter
chartbusfor the name, and accept all the remaining defaults. - Click Next and then Finish.
- Click Bus members under Topology on the chartbus detail page.
- Click Add and then select the server where you want DynamicChartsEAR.ear installed. Click Next.
- Accept the defaults and click Next, then Next again, and then Finish.
- Save the changes to repository.
- Restart the application server.
- Create the topic connection factory for DynamicCharts:
- Log on to the admin console and navigate to Resources => JMS => Topic connection factories.
- Select a server level scope.
- Click New. Select Default messaging provider and click OK.
- Enter
DynamicChartsfor name,jms/ChartPublishfor JNDI name, andchartbusfor Bus name, and keep all the remaining defaults. - Click Apply and then click Save to save the repository information.
- Install DynamicChartsEAR.ear:
- Log on to the admin console and navigate to Applications => Install New Application.
- Browse your file system and select DynamicChartsEAR.ear and click Next.
- Accept the defaults and click Next, then Next again, and then Finish.
- Click Save to save the master configuration.
- Start DynamicChartEAR.
- Launch this URL:
http://<host>:<port>/DynamicCharts/dynamic-charts.html.
The WebSphere Application Server Feature Pack for Web 2.0 provides a full solution for the most common requirements of building Ajax-based applications. This article explained how to create dynamic charts with the Dojo Toolkit, how you can reuse an existing service with the RPC adapter, and how you can integrate other applications and publish data changes to clients with Web messaging and the SIBus. The considerations and tips presented here will help you get a better understanding of the Web 2.0 feature pack so you can quickly and successfully build or enhance your own Ajax-based applications.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample application | ajax_chart_example_code.zip | 18 KB | HTTP |
Information about download methods
Learn
-
A look at the WebSphere Application Server Feature Pack for Web 2.0
-
WebSphere
Application Server documentation for Feature Pack for Web 2.0
-
Installing Feature Pack for Web 2.0 on distributed operating systems
-
The Book of Dojo
-
Service
Data Objects, WorkManager, and Timers: IBM and BEA Joint Specifications Overview
-
IBM developerWorks
WebSphere
Get products and technologies
-
Download
IBM WebSphere Application Server Feature Pack for Web 2.0,
includes product information
Li Long Chen is working as Associate I/T Architect for IBM Managed Business Process Services solution assets.
Elaine Zhan is working as an Advisory Software Engineer for IBM Managed Business Process Services solution assets.
Comments (Undergoing maintenance)





