Section 6.3. Using DWR with Ajax


6.3. Using DWR with Ajax

Direct Web Remoting (DWR) is an open source toolkit that's available from http://getahead.ltd.uk/dwr. It gives you everything you need to use Ajax in a Java web application. While DWR is not the only Ajax toolkit available for the Java platform, it is one of the most mature, and it offers a great deal of useful functionality.

DWR provides a set of server-side Java classes, including a servlet that runs the whole show, in one nice little file named dwr.jar. On the browser side, there's a JavaScript library that mirrors the server-side classes. The dwr.xml file provides the plumbing that connects the server-side classes with the JavaScript. That file resides with web.xml in the WEB-INF directory.

To demonstrate the DWR library, we'll create another zip code lookup page. We need only three classes: the connector class for the database, the Zipcode POJO class, and the ZipcodeManager class. To get started, download dwr.jar from http://getahead.ltd.uk/dwr and place it in the WEB-INF/lib directory of your application. DWR provides its own servlet, so our first task is to configure that servlet in web.xml:

 <servlet>     <servlet-name>dwr-invoker</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-invoker</servlet-name>     <url-pattern>/dwr/*</url-pattern> </servlet-mapping> 

The dwr.xml file controls the mirroring between the Java objects on the server and the client-side JavaScript, as you can see in Example 6-3.

Example 6-3. The control and plumbing for DWR stored in dwr.xml

 <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"     "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr>     <allow>         <create creator="new" javascript="ZipcodeManager"                 >             <include method="getZipcode"/>         </create>         <convert converter="bean" match="com.oreilly.ajax.Zipcode">             <param name="include" value="city,state,zipcode"/>         </convert>     </allow> </dwr> 

The <convert> tag tells JavaScript that there will be a Zipcode bean and that there will be support for city, state, and zipcode class variables that can be accessed following the JavaBean conventions (via getCity( ), getState( ), and getZipcode( )).

The <create> tag sets up the ZipcodeManager to have the JavaScript functions to support the getZipcode( ) method. That way, we can later make a reference to ZipcodeManager.getZipcode( ). We are mirroring only one method here, but you will usually need to mirror multiple methods. In that case, each method must be listed in its own <include> tag. For example, if you wanted a setZipcode( ) method, you would change the <create> portion of dwr.xml to look like this:

 <create creator="new" javascript="ZipcodeManager"         >     <include method="getZipcode"/>     <include method="setZipcode"/> </create> 

Of course, com.oreilly.ajax.ZipcodeManager would have to have the setZipcode( ) method as well. We're not supporting that feature, though; our ZipcodeManager class (presented in Example 6-4) only has the getZipcode(String zip) method.

Example 6-4. The ZipcodeManager class

 public class ZipcodeManager {     static public Zipcode getZipcode(String zip) {         Zipcode zipcode = null;         Connection con = DatabaseConnector.getConnection( );         String sqlString = "";         zipcode = new Zipcode( );         zipcode.setZipcode(zip); // put in original zip code         try {             sqlString = "SELECT CITY,STATE,ZIPCODE FROM ZIPCODES WHERE                         ZIPCODE='"+zip+"';";             Statement select = con.createStatement( );             ResultSet result = select.executeQuery(sqlString);             if (result.next( )) { // process results one row at a time                 zipcode.setCity(result.getString(1));                 zipcode.setState(result.getString(2));                 zipcode.setZipcode(result.getString(3));             }         } catch (Exception e) {             System.out.println("exception in login"+e.getMessage( ));         } finally {             if (con != null) {                 try {                     con.close( );                 } catch (SQLException e) {                 }             }         }         return zipcode;     } } 

Now we can reference the Java objects as if they existed in our JavaScript:

 function retrieveCityState( ) {     zip = document.getElementById("zipcode");     ZipcodeManager.getZipcode(zip.value,populateData); } function populateData(zipcode) {     document.getElementById('state').value=zipcode.state;     document.getElementById('city').value=zipcode.city; } 

The Java method ZipcodeManager.getZipcode(String zipcode) from Example 6-4 is different from the JavaScript method ZipcodeManager.getZipcode(String zipcode, function) called by retrieveCityState( ). DWR mirrors the Java methods almost exactly, but with an added parameter to handle the callback. That extra parameter tacked onto the end is the callback function that handles the data returning from the Ajax request.


Since DWR handles the communications between the client and the server, there's a lot less JavaScript to write. Further, it's a lot easier to see what the application is doing.

So, how does the JavaScript application know about the mapping to our server-side Java classes and methods? The application's HTML must import three files: dwr/engine.js, dwr/util.js, and a third file that DWR generates at runtime. The name of this third file is given by dwr.xml's <create> tag: the parameter javascript="ZipcodeManager" tells us to include ZipcodeManager.js in our HTML or JSP file. The dwrindex.html file is shown in Example 6-5.

Example 6-5. dwrindex.html

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>     <title>AJAX DWR Zipcode Lookup</title>     <script src='/books/4/163/1/html/2/dwr/interface/ZipcodeManager.js'></script>     <script src='/books/4/163/1/html/2/dwr/engine.js'></script>     <script src='/books/4/163/1/html/2/dwr/util.js'></script>     <script language="JavaScript" type="text/javascript">     function retrieveCityState( ) {         zip = document.getElementById("zipcode");         ZipcodeManager.getZipcode(zip.value,populateData);     }     function populateData(zipcode) {         document.getElementById('state').value=zipcode.state;         document.getElementById('city').value=zipcode.city;     }     </script> </head> <body>     <h1>AJAX ZIPCODES with DWR</h1>     <table align="left" >         <tr>             <td>Zip Code:</td>             <td align="left">                 <input type="text"  name="zipcode"                        onblur="retrieveCityState( )">             </td>         </tr>         <tr>             <td>City:</td>             <td align="left"><input type=text ></td>         </tr>         <tr>             <td>State:</td>             <td align="left"><input type=text ></td>         </tr>     </table> </body> </html> 

Figure 6-4 shows what the zip code lookup application created with DWR looks like.

Figure 6-4. Looking up zip codes with DWR


DWR is one of the best Ajax frameworks for Java out there. This example barely touches on its features. For example, if you have to make several calls, DWR supports call batching, which allows the application to group the remote calls, storing them up and then sending them together in a single larger remote call.

DWR also has built-in security and JavaScript helper methods to make the display easier to manage. Check out DWR's home page for more information (http://getahead.ltd.uk/dwr/documentation/); because DWR has been around longer than many other Ajax frameworks, you'll find a lot of good documentation on it.




Ajax on Java
Ajax on Java
ISBN: 0596101872
EAN: 2147483647
Year: 2007
Pages: 78

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net