Skip to main content

The XmlHttpProxy Client for Java

Posted by gmurray71 on July 17, 2006 at 12:49 PM PDT

One drawback of working with AJAX is that an AJAX-based client
cannot make calls to URLs outside of its domain, which means that it
cannot access services located on another server. A technique such
as href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/">JSONP
can help in this regard, but it has some limitations.  One
limitation is that including third-party
JavaScript inside script elements exposes your
application to potential
security risks because you are allowing external parties to interact
with your client.

To overcome these problems, you need a generic proxy that
can communicate with external services on your client's behalf.
The proxy passes a call from your client application to the
service, receives the content in response from the service, and returns
the content to your client. You can then use this content in
your AJAX-based application.

Using a generic proxy has other benefits. It can be a
buffer between third-party code and your application. It can also
perform data conversions to restrict the format of data that you allow to come from a third party.

Services that a generic proxy can work with include RESTful web
services such as the Flickr Image Search, an RSS feed, or the Yahoo
Geocoder Service. The proxy can return content from these services
"as is" to the client, or it can apply an XSLT transformation to it so
that the content is converted to a different content type, such as
JavaScript Object Notation (JSON).

The XmlHttpProxy Client

The XmlHttpProxy(XHP) is provided as part of jMaki.
When creating the XmlHttpProxy we created the API in such a way that it will work well with Project jMaki but also be useful as a generic Java based proxy which may be used with servlets, JSF components, or from the command line. The XmlHttpProxy client includes the following:

  • The XmlHttpClient which fetches the content using
    an HTTP client applies XSLT transformations (if necessary)
  • An HTTP client for accessing services
  • XmlHttpServlet, which is an provides Java
    Enterprise Edition clients an interface to the XmlHttpProxy client

The following sequence diagram shows how a JavaScript client (such as a
jMaki widget)
may use an AJAX request (using the XmlHttpRequest) to access the Yahoo
Geocoder service through the XmlHttpProxy client.
The Yahoo Geocoder service takes an address and returns its latitude
and longitude based on a address or location.

alt="XMLHttpProxy Request Sequence Diagram"
style="width: 630px; height: 284px;border:0">

As shown in the sequence diagram above, the XMLHttpProxyServlet instance
handles the XMLHttpRequest and passes it on to the XMLHttpProxy
client, which calls the service. The service then gets the XML
data and returns it to the XMLHttpProxy client, which
performs an XSLT transformation on the data to convert it to JSON. It
then passes the JSON content to the XMLHttpProxyServlet
instance, which passes it back to the client.

A request to the Yahoo Geocoder Service for the location "Sunnyvale" using the following URL:

http://api.local.yahoo.com/MapsService/V1/geocode?appid=YahooDemo&location=Sunnyvale

You may test this by entering the URL into your browser or running curl at any given time. The Yahoo GeoCoder service requires an
Yahoo API key provided using URL parameter appid. For your own applications please use your own application key. The address or location is provided using the URL parameter location. See The Yahoo Geocoding API documentation for more details.

A request to the URL http://api.local.yahoo.com/MapsService/V1/geocode?appid=YahooDemo&location=Sunnyvale
will return an XML document which appears as:

<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:yahoo:maps" xsi:schemaLocation="urn:yahoo:maps
" title="http://api.local.yahoo.com/MapsService/V1/GeocodeResponse.xsd">
">http://api.local.yahoo.com/MapsService/V1/GeocodeResponse.xsd">
<Result precision="city">
<Latitude>37.369019</Latitude>
<Longitude>-122.035019</Longitude><Address></Address>
<City>SUNNYVALE</City><State>CA</State><Zip></Zip>
<Country>US</Country>
</Result>
<Result precision="city">
<Latitude>37.050758</Latitude>
<Longitude>-94.495216</Longitude><Address></Address>
<City>SUNNYVALE</City><State>MO</State><Zip></Zip>
<Country>US</Country>
</Result>
<Result precision="city">
<Latitude>35.737659</Latitude>
<Longitude>-82.134827</Longitude><Address></Address>
<City>SUNNYVALE</City><State>NC</State><Zip></Zip>
<Country>US</Country>
</Result>
<Result precision="city">
<Latitude>32.796391</Latitude>
<Longitude>-96.563461</Longitude><Address></Address>
<City>SUNNYVALE</City><State>TX</State><Zip></Zip>
<Country>US</Country>
</Result>
</ResultSet>
<!--
ws02.search.scd.yahoo.com uncompressed/
chunked Fri Jul 14 11:18:51 PDT 2006
 -->

While we could parse thorough this in JavaScript code wouldn't it be better if we could have a JSON object? You can specify an XSL style sheet to provide a XML to JSON transformation. This may be done by providing a fully qualified URL to the XmlHttpProxyServlet using the URL parameter xslURL. In the case of the Yahoo Geocoder example uses the following style sheet on ajax.dev.java.net.
The resulting document appears as follows:

{"coordinates": [
       
           {
            "address" : "",
            "city" : "SUNNYVALE",
            "state" : "CA",
            "zip" : "",
            "latitude" : "37.369019",
            "longitude" : "-122.035019"
   }
           ,
           {
            "address" : "",
            "city" : "SUNNYVALE",
            "state" : "MO",
            "zip" : "",
            "latitude" : "37.050758",
            "longitude" : "-94.495216"
   }
           ,
           {
            "address" : "",
            "city" : "SUNNYVALE",
            "state" : "NC",
            "zip" : "",
            "latitude" : "35.737659",
            "longitude" : "-82.134827"
   }
           ,
           {
            "address" : "",
            "city" : "SUNNYVALE",
            "state" : "TX",
            "zip" : "",
            "latitude" : "32.796391",
            "longitude" : "-96.563461"
   }
   
        ]}

Now that we have the data in JSON it is very easy to access it from our JavaScript code. From the Dojo Toolkit for example we would use the following to access the XmlHttpProxy:

var loc = "Sunnyvale"; // this could be looked up from a form
var yahooService =
encodeURIComponent(
"http://api.local.yahoo.com/MapsService/V1/geocode" +
"?appid=YahooDemo&location=" + loc);
var xslURL =
encodeURIComponent(
"http://localhost:8080/jmaki/resources/xsl/" +
"yahoo-geocoder.xsl");
dojo.io.bind({
    url: "xhp?url=" + yahooService + "&xslURL=" + xslURL,
    mimetype: "text/json",
    load : function(type, data) {                               
            alert("latitude=" + data.coordinates[0].latitude);
   }
});"

In the example above an instance of the XmlHttpProxyServlet is mapped to the URI "/xhp". The Dojo client code uses dojo.io.bind to make an asynchronous request (AJAX) to the URL "xhp" with the location "Sunnyvale" and XSL stylesheet http://localhost:8080/jmaki/resources/xsl/ which is forwarded to the XmlHttpProxyServlet. The XmlHttpProxyServlet uses an instance of the XmlHttpProxy client to make an HTTP GET request to
the Yahoo Geocoder service. The Yahoo Geocoder services returns an XML document containg the coordiantes which is transformed to JSON and returned to the client.

With the Yahoo Geocoder there may be more than one set coordinates for any given location, as is the case with a request for the locaton "Sunnyvale." The XSL document will always generate JSON object always containg an array of coordinates for this very reason. The Dojo example above displays an alert dialog with the latitude from the first set of coordinates.

Next Steps for the XmlHttpProxy Client

The XmlHttpProxy now supports various services from Flickr, Yahoo, and RSS feeds that may be acessed using a standard HTTP or HTTPS get request. In the future we plan to improve the XmlHttpProxy to support HTTP Basic authentication and more complex interactions such as HTTP POSTs to the Flickr, Del.icio.us, and Flickr REST interfaces.

Resources

A more extensive writeup including more examples of the XmlHttpProxy client maybe found in the jMaki documentation.

The Java source for the XmlHttpProxy client is part of Project jMaki and may be accessed on java.net here.

The XSL Style Sheets for the services currently supported by the XmlHttpProxy client may be found at ajax.dev.java.net.

Download the jMaki sample application and view more documentation at jMaki Home Page.

Download GlassFish for which these examples are written to.

Now that you've seen it please go out and use the XmlHttpProxy and let us know what you think.

What services would you like supported with the XmlHttpProxy client?

Related Topics >>