jriaffe - Consuming Web Service
jriaffe - Consuming Web Service
Jriaffe is built to make creating rich internet applications easy. The goal is to produce several API’s that are easily integrated into your application. Currently Jriaffe provides an XMLWebService that allows you to make HTTP requests and an XMLBinder class to help process the response.
XMLWebService
The XMLWebService allows you to submit a HTTP request asynchronously. To interact with the service, you need to set the client data member of the XMLWebService. The ServiceClient is told how many bytes are expected to be downloaded. The client can also listen for specific XML nodes and can receive the entire document after it is downloaded. Lets take a look at a Groovy ServiceClient implementation that also executes a service call.
// class imlements ServiceClient interface
class LocalImageService implements ServiceClient {
def delegate
def url = "http://localhost/~preisler/jriaffeTestFiles/listImages.xml"
def XMLWebService execute() {
// create a list of nodes that this client is interested in
// being notified about
def nodes = ["result"];
// create the service request object. Tell it the URL, HTTP method
// ServiceClient, and nodes.
def service = new XMLWebService(url, HttpMethod.GET, this, nodes);
// execute the service. This call does not block.
service.execute(null)
return service;
}
// called when the HTTP request is done.
public void requestComplete(String xml) {
delegate.complete();
}
// called every time a “result” node is parsed in the download
public void dataRecieved(String name, String data) {
// The data passed in is XML. This is a map. The keys are the data member
// names in the Class. The values are the XML node
// names to map to the data members.
def fieldMap = [imageUrl:"imageUrl", height:"height", width:"width",
thumbnailUrl:"thumbnail/imageUrl",
thumbnailHeight:"thumbnail/height",
thumbnailWidth:"thumbnail/width"]
// create a binder
XMLBinder binder = new XMLBinder()
ImageInfo anImage = new ImageInfo()
// map the data from the XML passed in to the data object.
// “/result” is the root of the XML document.
binder.bind anImage, data, "/result", fieldMap
delegate.imageFound anImage
}
// called for any error that might occur during the download or parsing process
public void processingError(String message, Exception ex) {
delegate.error(message);
}
// called before the request starts and tells us how many bytes to expect
public void totalBytesExpected(long total) {
delegate.downloadSize(total);
}
// Tells us the total bytes downloaded so far. Is called in increments of
// 100 bytes by default.
public void downloadProgress(long bytesRead) {
delegate.dataRecieved(bytesRead);
}
}
This service client is from the jriaffeWebServiceDemo project. The service is executed in a separate thread behind the scenes. All call backs to the ServiceClient are called on the Swing event thread so the callbacks can update the UI directly.
XMLBinder
The XMLBinder allows you to easily map XML documents to objects. The API uses XPath expressions to map the XML attributes and nodes to an object’s data members. Lets assume we we have the following data member defined.
class ImageInfo {
private int thumbnailWidth;
//assume we have get and set methods for thumbnailWidth
}
Lets also assume we have the following XML document.
<result>
<imageUrl>
http://localhost/~preisler/jriaffeTestFiles/testImages/100_4084.JPG
</imageUrl>
<height>1932</height>
<width>2576</width>
<thumbnail>
<imageUrl>
http://localhost/~preisler/jriaffeTestFiles/testImages/100_4084.jpg
</imageUrl>
<height>270</height>
<width>360</width>
</thumbnail>
</result>
Now we can create an XML binder.
XMLBinder binder = new XMLBinder()
We create a Map with the field names and the XPath that maps the XML node to the data member.
def fieldMap = [thumbnailWidth:"thumbnail/width"]
Now lets do the mapping telling it that the root node is “result”.
ImageInfo anImage = new ImageInfo()
//data is the XML String
binder.bind anImage, data, "/result", fieldMap
The thumbnailWidth is now set to 360.