Wednesday, 28 March 2012

A Few Notes on Programming Web Services with XML-RPC

http://www.tutorialspoint.com/xml-rpc/xml_rpc_examples.htm gives the below example:

import org.apache.xmlrpc.*;

public class JavaServer {

public Integer sum(int x, int y) {
return new Integer(x+y);
}

public static void main (String [] args) {
try {

System.out.println("Attempting to start XML-RPC Server...");
WebServer server = new WebServer(80);
server.addHandler("sample", new JavaServer());
server.start();
System.out.println("Started successfully.");
System.out.println("Accepting requests. (Halt program to stop.)");
} catch (Exception exception) {
System.err.println("JavaServer: " + exception);
}
}
}

------------------------------------

import java.util.*;
import org.apache.xmlrpc.*;

public class JavaClient {
public static void main (String [] args) {
try {
XmlRpcClient server = new XmlRpcClient("http://localhost:80");
Vector params = new Vector();
params.addElement(new Integer(17));
params.addElement(new Integer(13));

Object result = server.execute("sample.sum", params);

int sum = ((Integer) result).intValue();
System.out.println("The sum is: "+ sum);

} catch (Exception exception) {
System.err.println("JavaClient: " + exception);
}
}
}

This requires: xmlrpc-1.2.jar
in the Java build path. It works OK. No problem.

I will use this example to solve minor problems of 3 examples from
books.google.com - "Programming Web Services with XML-RPC of Simon Laurent, Joe Johnston,
and Edd Dumbill."

The problems that I met are:


1- Installing the helma.xmlrpc Library
You can not find this lib because it has evolved toxmlrpc.jar
2-the location of the handler
The examples are given in such fashion that the position of the handler
is left ambiguous. It should be an inner class of the server class.
3- the handler must be static
4- client-or the server does not need io try catch
5- Some examples require import for io
6- port problem connection error
The examples suggests a port number which does not connect at least on my machine.

I removed param processing which can easily be restored. I also
put the server and client into the same project for simplicity.
You should put them in seperate projects also.

An example of batch running follows:

1- XML-RPChandler project


C:\Users\ars\Desktop\eclipseWS\eclipseJAXWSrpc\XML-RPCproject\bin>java -cp ../li
b/xmlrpc-1.2.jar;. JavaServer
Attempting to start XML-RPC Server...
Started successfully.
Accepting requests. (Halt program to stop.)


C:\Users\ars\Desktop\eclipseWS\eclipseJAXWSrpc\XML-RPCproject\bin>java -cp ../li
b/xmlrpc-1.2.jar;. JavaClient
The sum is: 30


The corrected and running solutions lie below:

import java.io.IOException;
//import helma.xmlrpc.WebServer;
//import helma.xmlrpc.XmlRpc;
import org.apache.xmlrpc.*;

public class AreaServer {

public static class AreaHandler {

public Double rectArea(double length, double width) {
return new Double(length * width);
}

public Double circleArea(double radius) {
double value = (radius * radius * Math.PI);
return new Double(value);
}

}

public static void main(String[] args) {
// if (args.length < 1) {
// System.out.println(
// "Usage: java AreaServer [port]");
// System.exit(-1);
// }

// try {

// Start the server, using built-in version
System.out.println("Attempting to start XML-RPC Server...");
// WebServer server = new WebServer(Integer.parseInt(args[0]));
WebServer server = new WebServer(80);

System.out.println("Started successfully.");

// Register our handler class as area
//server.addHandler("area", new AreaHandler());
server.addHandler("area", new AreaHandler());
System.out.println("Registered AreaHandler class to area.");
server.start();
System.out.println("Started successfully.");
System.out.println("Now accepting requests. (Halt program to stop.)");

// } catch (IOException e) {
// System.out.println("Could not start server: " +
// e.getMessage( ));
// }
}

}
----------------------------------
import java.io.IOException;
import java.util.Vector;
//import helma.xmlrpc.XmlRpc;
//import helma.xmlrpc.XmlRpcClient;
//import helma.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.*;

public class AreaClient {

public static void main(String args[]) {
// if (args.length < 1) {
// System.out.println(
// "Usage: java AreaClient [radius]");
// System.exit(-1);
// }

try {
// Create the client, identifying the server
XmlRpcClient client =
new XmlRpcClient("http://localhost:80/");

// Create the request parameters using user input
Vector params = new Vector( );
//params.addElement(new Double(args[0]));
params.addElement(new Double("5"));

// Issue a request
Object result =
client.execute("area.circleArea", params);

// Report the results
System.out.println("The area of the circle would be: " + result.toString( ));

} catch (IOException e) {
System.out.println("IO Exception: " + e.getMessage( ));
} catch (XmlRpcException e) {
System.out.println("Exception within XML-RPC: " + e.getMessage( ));
}
}

}



2.passing hash parameter example

import java.io.IOException;
import java.util.Hashtable;
//import helma.xmlrpc.WebServer;
//import helma.xmlrpc.XmlRpc;
import org.apache.xmlrpc.*;

public class AreaServer {

public static class AreaHandler {

public Double rectArea(double length, double width) {
return new Double(length * width);
}

public Double circleArea(double radius) {
double value = (radius * radius * Math.PI);
return new Double(value);
}

public Double anyArea(Hashtable arguments) {
Double value;
value=new Double(0);
String requestType=(String) arguments.get("type");
if (requestType.equals("circle")) {
Double radius=(Double) (arguments.get("radius"));
value=circleArea(radius.doubleValue( ));
}
if (requestType.equals("rectangle")) {
Double length=(Double) (arguments.get("length"));
Double width=(Double) (arguments.get("width"));
value=rectArea(length.doubleValue(), width.doubleValue( ));
}

return value;
}


}

public static void main(String[] args) {
// if (args.length < 1) {
// System.out.println(
// "Usage: java AreaServer [port]");
// System.exit(-1);
// }

// try {

// Start the server, using built-in version
System.out.println("Attempting to start XML-RPC Server...");
// WebServer server = new WebServer(Integer.parseInt(args[0]));
WebServer server = new WebServer(80);

System.out.println("Started successfully.");

// Register our handler class as area
//server.addHandler("area", new AreaHandler());
server.addHandler("area", new AreaHandler());
System.out.println("Registered AreaHandler class to area.");
server.start();
System.out.println("Started successfully.");
System.out.println("Now accepting requests. (Halt program to stop.)");

// } catch (IOException e) {
// System.out.println("Could not start server: " +
// e.getMessage( ));
// }
}

}
-------------------------------------------------
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
//import helma.xmlrpc.XmlRpc;
//import helma.xmlrpc.XmlRpcClient;
//import helma.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.*;

public class AreaClient {

public static void main(String args[]) {
// if (args.length < 1) {
// System.out.println(
// "Usage: java AreaClient [radius]");
// System.exit(-1);
// }

try {
// Create the client, identifying the server
XmlRpcClient client =
new XmlRpcClient("http://localhost:80/");

// Create a double from the user argument
//Double radius=new Double(args[0]);
Double radius=new Double("5");

// Create a hashtable and add a circle request
Hashtable requestHash = new Hashtable( );
requestHash.put("type", "circle");
requestHash.put("radius", radius);

// Create the request parameters using user input
Vector params = new Vector( );
params.addElement(requestHash);

// Issue a request
Object result =
client.execute("area.anyArea", params);

// Report the results
System.out.println("The area of the circle would be: " + result.toString( ));


} catch (IOException e) {
System.out.println("IO Exception: " + e.getMessage( ));
} catch (XmlRpcException e) {
System.out.println("Exception within XML-RPC: " + e.getMessage( ));
}
}

}


3. log service program
import java.io.IOException;
//import helma.xmlrpc.WebServer;
//import helma.xmlrpc.XmlRpc;
import org.apache.xmlrpc.*;

public class XLogServer {

public static class XLogHandler {
public String XLogReport(String address, String message) {
System.out.println("From: " + address);
System.out.println("Message: " + message);
return "ack";
}
}

public static void main(String[] args) {
// if (args.length < 1) {
// System.out.println("Usage: java AreaServer [port]");
// System.exit(-1);
// }

// try {
// Start the server, using built-in version
System.out.println("Attempting to start XML-RPC Server...");
// WebServer server = new WebServer(Integer.parseInt(args[0]));
WebServer server = new WebServer(Integer.parseInt("80"));

System.out.println("Started successfully.");

// Register our handler class as area
server.addHandler("XLog", new XLogHandler());
System.out.println("Registered XLogHandler class to XLog.");
server.start();
System.out.println("Started successfully.");
System.out.println("Now accepting requests. (Halt program to stop.)");

// } catch (IOException e) {
// System.out.println("Could not start server: " +
// e.getMessage( ));
// }
}
}
-----------------------------------------------------------
import java.io.IOException;
import java.net.*;
import java.util.Vector;
//import helma.xmlrpc.XmlRpc;
//import helma.xmlrpc.XmlRpcClient;
//import helma.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.*;

public class XLogClient {

public static void main(String args[]) {
try {
throw new Exception("help");
} catch (Exception e) {
report (e);
}
}

public static void report(Exception eReport) {
try {
// Create the client, identifying the server
XmlRpcClient client =
new XmlRpcClient("http://127.0.0.1:80/");
//new XmlRpcClient("http://192.168.2.191:80/");

//get local hostname and IP address
InetAddress address=InetAddress.getLocalHost( );
String ipAddress=address.toString( );

// Create the request parameters using user input
Vector params = new Vector( );
params.addElement(ipAddress);
params.addElement(eReport.getMessage( ));
// Issue a request
Object result =
client.execute("XLog.XLogReport", params);

// Report the results - this is just for the example
// In production, the 'ack' will be thrown away.
// Alternatively, the log system could be more interactive
// and the result might have meaning.
System.out.println("Response was: " + result.toString( ));

//If we can't report to server, report locally
} catch (IOException e) {
System.out.println("IO Exception: " + e.getMessage( ));
} catch (XmlRpcException e) {
System.out.println("Exception within XML-RPC: " + e.getMessage( ));
}
}
}

4. getting and setting a value

import java.io.IOException;
//import helma.xmlrpc.WebServer;
//import helma.xmlrpc.XmlRpc;
import org.apache.xmlrpc.*;

public class GetSetServer {

public static class GetSetHandler {
protected int value;

public GetSetHandler(int initialValue) {
value = initialValue;
}

public int getValue(String requester) {
return value;
}

public int setValue(String requester, int newValue) {
value = newValue;
return value;
}
}

public static void main(String[] args) {
// if (args.length < 1) {
// System.out.println(
// "Usage: java GetSetServer [port]");
// System.exit(-1);
// }
// try {
// Start the server, using built-in version
System.out.println("Attempting to start XML-RPC Server...");
// WebServer server = new WebServer(Integer.parseInt(args[0]));
WebServer server = new WebServer(Integer.parseInt("80"));

System.out.println("Started successfully.");

// Register our handler class as area
server.addHandler("getSet", new GetSetHandler(20));
System.out.println("Registered GetSetHandler class to getSet.");
server.start();
System.out.println("Started successfully.");
System.out.println("Now accepting requests. (Halt program to stop.)");

// } catch (IOException e) {
// System.out.println("Could not start server: " +
// e.getMessage( ));
// }
}
}
-------------------------------------------------
import java.io.IOException;
import java.net.*;
import java.util.Vector;
//import helma.xmlrpc.XmlRpc;
//import helma.xmlrpc.XmlRpcClient;
//import helma.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.*;

public class GetSetClient {

public static void main(String args[]) {
if (args.length < 1) {
System.out.println(
"Usage: java GetSetClient [get set] [value]");
System.exit(-1);
}

String getOrSet=new String(args[0]);

if (!((getOrSet.equals("get")) (getOrSet.equals("set")))) {
System.out.println(
"First argument must be get or set");
System.exit(-1);
}

try {
// Create the client, identifying the server
XmlRpcClient client =
new XmlRpcClient("http://localhost:80/");

//get local host IP address
InetAddress address=InetAddress.getLocalHost( );
String ipAddress=address.toString( );

// Create the request parameters using user input
Vector params = new Vector( );
params.addElement(ipAddress);
if (getOrSet.equals("set")) {
Integer newValue=new Integer(args[1]);
params.addElement(newValue);
}

// Issue a request
Object result=null;
if (getOrSet.equals("set")) {
result = client.execute("getSet.setValue", params);
} else {
result = client.execute("getSet.getValue", params);
}

// Report the results
System.out.println("The response was: " + result.toString( ));

} catch (IOException e) {
System.out.println("IO Exception: " + e.getMessage( ));
} catch (XmlRpcException e) {
System.out.println("Exception within XML-RPC: " + e.getMessage( ));
}
}
}