Accessing External Resources With the XMLHttpProxy Client

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 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, 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

jMaki provides a generic proxy to services in the form of the XmlHttpProxy (XHP) client. The XHP client includes the following:

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 XHP client. The Yahoo GeoCoder service takes an address and returns its latitude and longitude.  You can browse the code for the example jMaki widget that accesses the Yahoo GeoCoder service on XMLHttpProxy Request Sequence Diagram

Figure 1: Generic Proxy Request Sequence Flow Diagram

As shown in Figure 1, 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 transform 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.

Calling the Yahoo GeoCoder Service Using the XMLHttpProxy

Let's take a look at how the application makes a request for the data.  In the jMaki sample application, the XMLHttpProxy client is mapped to the URL /xhp.  A request to the Yahoo GeoCoder service can be created by taking the location from a form field, as shown in Code Example 1.

Code Example 1: Sample URL to the Yahoo GeoCoder Service

Because we are passing this URL as a single parameter of a request to a server side component, such as a servlet, we need to encode the parameters we add to the URL in an HTTP-friendly way such that it does not interfere with other parameters. This can be done using the JavaScript encodeURIComponent built-in function. For example from JavaScript you can URI encode the URL using the following JavaScript code:

var location = encodeURIComponent("location=sunnyvale ca");
var url = "xhp?id=yahoogeocoder&urlparams=" + location;

Code Example 2:Encoding URL parameters

The XmlHttpProxy and the XmlHttpProxyServlet which provides web applications access to the proxy restrict access based on tokens. A token (id) is mapped to a set of parameters which include the service URLs, service API keys, XSL style sheets, and default values used by the XmlHttpProxy. Following is an example of the JSON based configuration file for the XmlHttpProxyServlet.

{"xhp": {
    "version": "1.1",
    "services": [
        {"id": "yahoogeocoder",
         "apikey" : "appid=jmaki-key",
         "xslStyleSheet": "yahoo-geocoder.xsl",
         "defaultURLParams": "location=santa+clara,+ca"
        {"id": "flickrtagsearch",
         "apikey" : "api_key=06d3805b73897217be9e0b532c85b15e",
         "xslStyleSheet": "flickr-search.xsl",
         "defaultURLParams": "tags=theKt"
        {"id": "yahoosearch",
         "apikey" : "appid=jmaki-key",
         "defaultURLParams": "query=jMaki"

Code Example 3: Token Mapping file for the XmlHttpProxy

Using token based restriction to resources allows you to consolidate what may be accessed and provide defaults. In the example above id is the token passed by a client to the XmlHttpProxyServlet along with some other parameters such as the location which is needed by the Yahoo Geocoder.


Code Example 4: Sample URL to the Yahoo GeoCoder Service

You may test the Yahoo GeoCoder service API at any time by simply entering the URL above into the location bar of your web browser. If you get a "403 Forbidden Error " The XMLHttpProxyServlet is doing its job. Direct access to the XMLHttpProxyServlet is restricted. What you can do is access the first page of the jMaki sample application to establish an HttpSession then access the URL again. For more on the motivations of restricting access to the XMLHttpProxyServlet see Restricting Access to your AJAX Services.


Followed by:


Code Example 5: Establishing a HttpSession Before Accessing a the XMLHttpProxyServlet

The format of the data shown in Code Example 5 might not be want to send your client. If it's not, you can modify this XSL style sheet while the application is running, allowing you to more quickly integrate new services. The example jMaki example application uses the following XSL stylesheet to transform the response shown in Code Example 5 from the Yahoo GeoCoder service to JSON.

<xsl:stylesheet version='1.0'
xmlns:yn="urn:yahoo:maps" >

<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="text()"/>
<xsl:template match="@*"/>

<xsl:template match="yn:ResultSet">
{"coordinates": [

<xsl:template match="yn:Result">
"address" : "<xsl:value-of select="yn:Address"/>",
"city" : "<xsl:value-of select="yn:City"/>",
"state" : "<xsl:value-of select="yn:State"/>",
"zip" : "<xsl:value-of select="yn:Zip"/>",
"latitude" : "<xsl:value-of select="yn:Latitude"/>",
"longitude" : "<xsl:value-of select="yn:Longitude" />"
<xsl:if test="position() < last()">,</xsl:if>

Code Example 6: Stylesheet Used to Convert XML data Returned From Yahoo GeoCoder Service to JSON

If you include an XSL stylesheet in your web application, you can apply it to the data by specifying the URL to the stylesheet as a parameter to the XmlHttpProxy client. The jMaki sample application includes the Yahoo Geocoder XSL stylesheet internally or you can place one on the WEB-ROOT/resources/xsl + xslStyleSheet directory. If the XSL styel sheet is not found there the class path is searched /META-INF/resources/ + xslStyleSheet (for example http://localhost:8080/jmaki/resources/xsl/yahoo-geocoder.xsl). When the stylesheet is found, the XmlHttpProxyServlet instance applies the XSLT transformation. The resulting document will be 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"
Code Example 7: Re-styled Data

Now that we have the data from the Yahoo GeoCoder Service in the format we need, we are ready to use use it ino our JavaScript clients. The folowing section covers how to use the data provided by XmlHttpProxy in your JavaScript applications.

Calling the XmlHttpProxy From Your JavaScript Clients

Now that we have seen how the XmlHttpProxy works, let's look at how you can use it from within a JavaScript client to fetch a JSON string and make that available to your application. The following code shows how you would obtain the coordinates for the location "sunnyvale" from the Yahoo GeoCoder using the XmlHttpProxyServlet.

function GeoCoder() {
	var uuid = widget.uuid;
	var service = widget.service;
    var location;
	this.getCoordinates = function() {
        location = encodeURIComponent(document.getElementById(uuid + "_location").value);
		var encodedLocation = encodeURIComponent("location=" + location);
        var url = jmaki.webRoot + "/" + service + "?id=yahoogeocoder&urlparams=" + encodedLocation;
        jmaki.doAjax({url: url, callback: function(req) { var _req=req; postProcess(_req);}});
    function postProcess(req) {
        if (req.readyState == 4) {
            if (req.status == 200) {
				var response = eval("(" + req.responseText + ")");
				jmaki.publish("geocoder", response.coordinates);

Code Example 8: Evaluating the Response with AJAX

Code Example 8 shows the widget code using the built-in jMaki doAjax function, which is a generic XmlHttpRequest call.  jMaki supports an implict property called jmaki.webRoot, which contains the URL to the base of the web application.  Now let us look at how we can access the XmlHttpProxyServlet instance from a Dojo client.

var location = encodeURIComponent("location=sunnyvale ca");{ 
    url: "xhp?id=yahoogeocoder&urlparams=" + location,
    mimetype: "text/json",
    load : function(type, data) {                                
            alert("latitude=" + data.coordinates[0].latitude);

Code Example 9: Evaluating the Response with AJAX Using DOJO

Code Example 9 shows how to use the function of the Dojo Toolkit to access the XmlHttpProxyServlet instance, which is mapped to the URL xhp.  From this instance, the application can access the contents of the Yahoo GeoCoder service. Notice that the extra parameters (location in Example 9) are encoded using the JavaScript encodeURIComponent function to ensure they are properly sent to the XmlHttpProxyServlet.

Calling the XmlHttpProxy From Your Java Clients

Instead of running the XHP client from JavaScript code, you can run it from the Java code in your own Java Enterprise Edition components, such as from servlets or JavaServer Faces components. You can also run it from the command line J2SE clients for the purpose of unit testing and development. The following code snippet shows how you can call the Yahoo GeoCoder using the XmlHttpProxy from your own code.

XmlHttpProxy xhp = new XmlHttpProxy();

InputStream xslInputStream = null;
String urlString =
"" +
String xslURLString =

Map paramsMap = new HashMap();
// add parameters if any here

URL xslURL = new URL(xslURLString);
if (xslURL != null) {
xslInputStream = xslURL.openStream();
} else {
System.err.println( "Error: Unable to locate XSL at URL " + xslURLString);
xhp.doGet(urlString, System.out, xslInputStream, paramsMap);

Code Example 10:  Calling the Yahoo GeoCoder Service using the Java Programming Language

Keep in mind that the XSL stylesheet, yahoo-geocoder.xsl,  must be available at the URL http://localhost:8080/jmaki/resources/xsl/yahoo-geocoder.xsl. If you are calling it from the comamand line, the URL may appear as file:src/conf/META-INF/resources/yahoo-geocoder.xsl.

Configuring a Proxy Server with the XmlHttpProxy

When using the XmlHttpProxy from behind a firewall you may need to set a proxy server and port name. This can be done using Servlet context parameters in the web.xml as follows:


The XmlHttpProxy servlet will now use the proxy server myproxyserver.eng on port 8080 to access the target content / service

Configuring the XmlHttpProxy to allow for Cross Domain Calls

The XmlHttpProxy allows you to support JSONP style interactions where a client in another domain can use your proxy. This is turned off by default with the XmlHttpProxy but can be enabled using the following Servlet context parameters.


This configuration will allow a client to make a call like using a script tag that to which the XmlHttpProxy will return a JSON string.