Skip to main content

Ajax and XML-RPC

Posted by analogueboy on April 23, 2005 at 9:16 AM PDT

Theres a lot of hype surrounding Ajax on
developer's blogs right now. As with most new technologies, there is an initial period of
frantic usage as people grapple with the new toy, but eventually some patterns and best
practices appear which simplify the use of the technology and make it easier for developers
to leverage without creating projects that become a nightmare to maintain.

Ajax promises a lot to developers of web applications. It allows the developer to load a
discrete unit of a page rather than forcing a complete page refresh. The end result is an
application that generally feels faster, whilst simplifying the maintenance of server side
state when several components are displayed on a single page.

In this post I'm going to look at one of the strongest candidates for the new standard in Ajax
communication, the incredibly simple XML-RPC protocol. I'm
going to use the Apache XML-RPC library to create a
simple web service and create a simple Java consumer before looking at how we can use the
JSolait JS XML-RPC library to consume the same service in a
browser window.

I'm going to create a small web application that we can drop into our servlet container to provide
a demo service, in this case a simple echo service. I'll show you a simple handler first, then the servlet
that loads the handler before creating the Java client. When thats all working, I'll create a
Javascript, browser-based client.

First things first, lets create the handler for our service. You'll notice that this class is a simple
POJO with no dependencies on the Apache framework.

package com.ellisonbrookes.xmlrpc.tutorial;

import java.io.Serializable;

/**
* @author Graham O'Regan @ Ellison Brookes
*/
public class EchoHandler implements Serializable {

    public String echo(String input) {

        return input;
    }

}

Now we need to create a servlet to load our handler within our servlet container. Its worth pointing
out that a servlet container isn't required, the Apache XML-RPC has a simple server included for testing
but I'd recommend that you use a servlet container for production services.

package com.ellisonbrookes.xmlrpc.tutorial;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.xmlrpc.XmlRpcServer;

/**
* @author Graham O'Regan @ Ellison Brookes
*/
public class XmlRpcServlet extends HttpServlet {

    /**
     * Create an instance of an XML-RPC server and register the
     * EchoHandler with it under the name "echoHandler".
     *
     * Then handle a request to the XML-RPC server, gather the data posted
     * to the servlet and then write the response to the output stream
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        XmlRpcServer server = new XmlRpcServer();
        server.addHandler("echoHandler", new EchoHandler());

        byte[] result = server.execute(request.getInputStream());

        String res = new String(result);
        response.setContentType("text/xml");
        response.setContentLength(result.length);
        OutputStream out = response.getOutputStream();
        out.write(result);
        out.flush();
    }

}

This is a very simple example of how we can use a servlet as the entry point to our service. In this example
we load our XmlRpcServer and register our handler under the name "echoHandler" before accepting the request
from the client.

Now lets create a client in Java to use this service. You need to create an XmlRpcClient which acts as our
proxy to the XML-RPC server. Parameters are passed in a single Vector and the Apache library will take care
of extracting the entries and passing them to the server. Then we pass the vector of parameters to client
along with the name of the service we want to call. Finally, we write the response to stdout.

package com.ellisonbrookes.xmlrpc.tutorial;

import java.io.IOException;
import java.util.Vector;

import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;

/**
* @author Graham O'Regan @ Ellison Brookes
*/
public class Client {

    public static void main(String[] args) throws XmlRpcException, IOException {

        XmlRpcClient xmlRpcClient = new XmlRpcClient("http://localhost:8080/xmlrpc/test.rpc");

        Vector parameters = new Vector();

        parameters.add("Hello World");

        String response = (String) xmlRpcClient.execute("echoHandler.echo", parameters);

        System.out.println("Response from server : " + response);
    }

}

So now we have created a simple web service and a client to consume them. Now lets create a Javascript
client for the service. This snippet shows how to set up a proxy to the server, passing in the names of
the methods that are required. If the methods are now specified it will try to use introspection to find out
what methods are available, but I'm not going to cover that here.

<script type="text/javascript" src="./jsolait/init.js"></script>
<script type="text/javascript" src="./jsolait/lib/urllib.js"></script>
<script type="text/javascript" src="./jsolait/lib/xml.js"></script>
<script type="text/javascript" src="./jsolait/lib/xmlrpc.js"></script>
<script type="text/javascript">
<!--
/**
* Load the xmlrpc object and a proxy to the service
*/
var xmlrpc = null;
var server = null;

try{
    var xmlrpc = importModule("xmlrpc");
    var server = new xmlrpc.ServerProxy('http://localhost:8080/xmlrpc/test.rpc', ['echoHandler.echo']);
}catch(e){
    reportException(e);
    throw "importing of xmlrpc module failed.";
}

/**
* Delete the value in the first box and put the result of the XML-RPC
* call into the second
*/
function echo(input){
response = server.echoHandler.echo(input);
document.myForm.input.value = "";
document.myForm.result.value = response;
}
//-->
</script>

This example imports the JSolait library and sets up the proxy to the service that we use for the client/server
communication which takes the URL for the XML-RPC server and passes in the name of the service(s) that
it intends to call. In the echo(input) method we call the echo method on our handler, remove the value
from the first input field and then assign the value of the result to the second input field.

So we've looked at how to create an XML-RPC server and register new handlers and create a client in Java and
Javascript. There are a lot of developers forming their own method of dealing with this technology, but I
believe that it would be more worth while to use a standard protocol for the client/server communication, it
will certainly be easier to maintain in the longer term. You can see how simple a protocol it is, and, whilst it
is limited compared to Corba or SOAP, it does allow a developer to quickly expose functionality to third parties
regardless of the language used on either side. I've always been impressed with the quality of the exception
handling of the Apache library too, it provides an accurate report of any exceptions thrown which makes debugging
an awful lot easier.

Here is the demo WAR file, the source for the Java components is under the WEB-INF/src directory download

Related Topics >>