From EJB 3 To AJAX: Part 2 - Integrating Java with JavaScript by DWR
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
|