Arch2Arch Tab BEA.com
Syndicate this blog (XML)

From EJB 3 To AJAX: Part 2 - Integrating Java with JavaScript by DWR

Bookmark Blog Post

del.icio.us del.icio.us
Digg Digg
DZone DZone
Furl Furl
Reddit Reddit

Pinaki Poddar's Blog | May 21, 2006  11:36 PM | Comments (1)


From EJB 3 to AJAX : Integrating Java and JavaScript using DWR In the previous blog, we described the server application based on EJB 3.0 doamin model that interacts with the datastore via Java Persistence Architecture. In this blog, I will describe how to connect an asynchronous JavaScript based browser application to the server side Java objects.

Out of many possible alternatives, I picked Direct Web Remoting. They appeared straight-forward and well-documented. I also looked into Backbase and Dojo. Both of them appeared to be more focussed on JavaScript application framework, while all I was looking for is a light-weight solution for a Java to JavaScript converter and DWR seemed to fit the bill.

Configuring DWR

How does DWR work? My first impression is it adds a servlet uk.ltd.getahead.dwr.DWRServlet in the application server's servlet container that converts Java to JavaScript. The servlet is configured with the mapping between Java and JavaScript objects. The servlet is specified in the web.xml of the web module as follows:

<!-- ======================================================================= -->
<!-- Direct Web Remoting Servlet description                                 -->
<!-- ======================================================================= -->
	<servlet>
	  <servlet-name>dwr-ejax</servlet-name>
	  <display-name>DWR Servlet</display-name>
	  <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
	  <init-param>
	     <param-name>debug</param-name>
	     <param-value>true</param-value>
	  </init-param>
	 </servlet>

	<servlet-mapping>
	  <servlet-name>dwr-ejax</servlet-name>
	  <url-pattern>/dwr/*</url-pattern>
	</servlet-mapping>
Kept the debug flag on as I was trying to peek what it does.

The classes are configured in a separate descriptor dwr.xml. The configuration specifies the classes that DWR is allowed to create and convert. Their idea seems to be conservative (they are from United Kingdom) -- they don't mess with your Java classes unless explictly instructed. So we specify the classes that are allowed to be instantiated and converted as follows

<!-- ======================================================================= -->
<!-- Configure marshalling of between Java and JavaScript objects            -->
<!-- ======================================================================= -->
  <allow>
    <create creator="new" javascript="ReviewService">
      <param name="class" value="ejax.service.ReviewService"/>
    </create>
     <convert converter="bean" match="ejax.domain.Item">
    </convert>
  </allow>
I have cited a single class for creation and conversion but the actual configuration specifies all the domain classes be instantiated and converted and the service class ejax.service.ReviewService be only instantiated. The service class being stateless, there is no need to convert its state.

Asynchronous JavaScript Programming

Now the hardest part for me. I need to write a JavaScript based application that follows asynchronous programming model! And I do not even have a editor that highlights syntax properly. Anyway, I began,

<!-- ======================================================================= -->
<!-- Header of the DWR based EJB3+AJAX client                                -->
<!-- ======================================================================= -->
<HTML>
<HEAD>
<script type='text/javascript' src='/ejax/dwr/engine.js'/>
<script type='text/javascript' src='/ejax/dwr/util.js'/>
<script type='text/javascript' src='/ejax/dwr/interface/Item.js'/>
  
The first two includes two java script libraries engine.js and util.js and the third being JavaScript version of one of the domain classes.

Where is DWR JavaScript libraries engine.js and util.js? Found them in dwr.jar -- a compact package of 183 KB. It also had the entry point servlet uk.ltd.getahead.dwr.DWRServlet.

Finally, I am ready to write my first JavaScript. I opted for a humble beginning. I wanted to get all the Books and display them in a table. The server side had the following method signature

public List getExtentByType(String queryClass)

This method takes a unqualified class name such as "Book" or "Music"and returns the entire extent by making a Java Persistence Query Language (JPQL) query
SELECT i FROM queryClass i.

How does one call that server side function from JavaScript program?

  
  function getExtent(itemType)
  {
     ReviewService.getExtentByType(fillTable,itemType);
  }
  
  
ReviewService is a JavaScript object corresponds to ejax.service.ReviewService that DWR has created because we told it so in dwr.xml. This JavaScript version mirrors all the methods original Java class had but there are provisions to exclude methods through dwr.xml. See their documentaion for further details.

Callback Function Pointer

But the created JavaScript object method has changed the original signature in an important and interesting way. Notice the first parameter fillTable. That is pointer to a JavaScript function. DWR servlet will callback this function with the data returned by ejax.service.ReviewService.getExtentByType() method after converting the result to corresponding to JavaScript objects. And as we have seen what is allowed to be converted is specified in dwr.xml. Here is the body of the callback method fillTable()
  
  function fillTable(items) 
  {
    DWRUtil.removeAllRows("itemTable");
    DWRUtil.addRows( "itemTable", items,[getId,getTitle,getArtist,getReviewCount,getRating]);
  }  
  var getId          = function(item) { return item.id };
  var getTitle       = function(item) { return item.title };
  var getArtist      = function(item) { return item.artist.name };
  var getReviewCount = function(item) { return item.reviews.length };
  var getRating      = function(item) { return item.rating };
  
  
  
The returned java.util.List<Book> from the server side Java has been converted to array of JavaScript Book objects by DWR servlet and it has called the fillTable() function with the array as parameter. DWR also provided utility functions to render a HTML table with data. The rest was easy even for a JavaScript novice.

Ready to launch

Packaging the application is simple. The application.xml specifies two modules: one contains all the Java classes and persistence.xml that configures the JPA provider BEA Kodo 4.0. The other is the web module that contains DWR library (dwr.jar) and the JavaScript program code in ejax.html.
   <application>
	<module>
	  <web>
		<web-uri>ejax.war</web-uri>
		<context-root>ejax</context-root>
	  </web>
	</module>	
	<module>
	  <ejb>ejax.jar</ejb>
	</module>
   </application>
   
The web module ejax.war
   106 Sun May 21 21:19:34 PDT 2006 META-INF/MANIFEST.MF
  1774 Sun May 21 20:47:54 PDT 2006 WEB-INF/web.xml   
  2803 Sun May 21 21:14:50 PDT 2006 WEB-INF/dwr.xml
183622 Tue May 09 14:31:46 PDT 2006 WEB-INF/lib/dwr.jar
  9560 Sun May 21 21:03:10 PDT 2006 ejax.html
  

and the ejb module in ejax.jar

   106 Sun May 21 21:19:34 PDT 2006 META-INF/MANIFEST.MF
  3280 Sat May 13 15:04:26 PDT 2006 META-INF/data.properties
  1706 Sun May 21 18:16:30 PDT 2006 META-INF/persistence.xml
  3211 Sun May 21 21:19:34 PDT 2006 ejax/domain/*.class
 1139 Sun May 21 21:19:32 PDT 2006 ejax/service/*.class
  

and finally the application packet ejax.ear

   106 Sun May 21 21:19:34 PDT 2006 META-INF/MANIFEST.MF
   845 Sun May 21 20:59:08 PDT 2006 META-INF/application.xml
 32221 Sun May 21 21:19:36 PDT 2006 ejax.jar
266701 Sun May 21 21:19:36 PDT 2006 ejax.war
  

Download

The sample application source code is available for download. A build.xml is provided to compile, build and deploy the application. In the nex blog, I will discuss how to develop a Session Bean version of the same application based on JPA.

Comments

Comments are listed in date ascending order (oldest first) | Post Comment

  • Hi there, im currently learning to use DWR on BEA WEblogic and ive also done some examples and find them very amusing because of its light weight. On my current project, we are using a framework wherein we are loading several web applications. In this case we have a front end application which serve as a container for the other application. My current problem now on using DWR is, it was implemented on the the application being loaded and once a jsp is loaded it cannot find the java class that was converted to javascript. Any ideas? thanks

    Posted by: hellFOX76 on July 19, 2007 at 7:36 AM



Only logged in users may post comments. Login Here.

Powered by
Movable Type 3.31