I am new to xmlrpc and take over an project now.
When I read the java code, I found all the xmlrpc was just sending primary type of data such as Integer or String. or send a map data structure of this primary type data.
I wonder if it could send a Object through the xmlrpc call.
e.g.
class Person{
int age;
String name;
Person dad;
Person mon;
public void method1{
…
}
}
Could an instance of Person could be sent by xml-rpc? If it is possible, could you give me some reference or related document to read to understand deeper? thanks a lot.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There are ways to send a a Person object over XML-RPC using the Redstone Library. But it is important to realize that the XML-RPC protocol is designed to only allow primitives, maps (as XML-RPC structs), and arrays. So once a Person object has been translated into an XML-RPC message, the fact that it was converted from a Person to an XML-RPC is lost. That is, Redstone XML-RPC will translate the Person object into a struct which will be deserialized into some kind of map/dictionary/hash on the receiving end. It is not possible to send a Person and have it be deserialized on the receiving and as a Person.
So, there are two ways:
1. You can implement an XmlRpcSerializer-class that you register with the XmlRpcClient. Redstone XML-RPC already contains a bunch of serializers that you can have a look at, but basically it would look something like this (psuedo-code):
public class PersonSerializer implemts XmlRpcSerializer {
public Class getSupportedClass() {
return Person.class
}
public void serialize(
Object value,
Writer writer,
XmlRpcSerializer builtInSerializer )
throws XmlRpcException, IOException
{
Person person = (Person) value;
// Another alternative would be to create a HashMap and just copy the values you want from the
// Person object and ask the builtInSerializer to serialize the HashMap. Like below:
2. The Redstone Library has a built-in Introspecting serializer that kicks in when an unknown object is being serialized. The introspecting serializer will look for all public getter-methods on the object and create the struct from that.
So if your Person class has the public methods getName(), getAge(), getDad(), getMom(), the serializer will create a struct with the keys "name", "age", "dad", "mom" in the message and will serialize the values returned by the getters to the XML-RPC message. Nested objects should work - when serializing the Person getDad() value, a nested struct will be created in the message, and so on.
So you can serialize complete object trees to nested XML-RPC structs using just the built-in Introspecting serializer. Note that it must be a tree, in the sense that you don't have cycles in the object graph.
Alternative 1. above is more flexible since you can name the keys in the struct whatever you want. So you can use key names that match the XML-RPC API you are interfacing with even if the Person objects properties don't inherently match the API.
The reason for implementing a PersonSerializer rather than just manually converting the Person to a HashMap and send directly to the XmlRpcClient is that the serializer is registered with the XmlRpcClient and will be invoked whenever and wherever a Person object is being sent. So you can build an object tree with Person-objects here and there, and even nested as in your case, and the XmlRpcClient will invoke your serializer whever it stumbles upon a Person.
If the XML-RPC server API you are invoking matches 100% with the properties in your Person class, than you can just pass it directly to the XmlRpcClient (given that you have public getters for the values in Person that you want to send). If not, you're best off implementing a PersonSerializer and select exactly what you want from the Person (and you'll have the opportunity to rename keys in the struct and do any transformations you like).
Again, the key thing to realize is that in XML-RPC there's just primitives, structs, and arrays. And the XML-RPC server may not be implemented in Java and it's API should be documented using just primitives, structs (and their keys), and arrays so that any XML-RPC library can be used.
Best Regards,
Greger
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am new to xmlrpc and take over an project now.
When I read the java code, I found all the xmlrpc was just sending primary type of data such as Integer or String. or send a map data structure of this primary type data.
I wonder if it could send a Object through the xmlrpc call.
e.g.
class Person{
int age;
String name;
Person dad;
Person mon;
public void method1{
…
}
}
Could an instance of Person could be sent by xml-rpc? If it is possible, could you give me some reference or related document to read to understand deeper? thanks a lot.
There are ways to send a a Person object over XML-RPC using the Redstone Library. But it is important to realize that the XML-RPC protocol is designed to only allow primitives, maps (as XML-RPC structs), and arrays. So once a Person object has been translated into an XML-RPC message, the fact that it was converted from a Person to an XML-RPC is lost. That is, Redstone XML-RPC will translate the Person object into a struct which will be deserialized into some kind of map/dictionary/hash on the receiving end. It is not possible to send a Person and have it be deserialized on the receiving and as a Person.
So, there are two ways:
1. You can implement an XmlRpcSerializer-class that you register with the XmlRpcClient. Redstone XML-RPC already contains a bunch of serializers that you can have a look at, but basically it would look something like this (psuedo-code):
public class PersonSerializer implemts XmlRpcSerializer {
public Class getSupportedClass() {
return Person.class
}
public void serialize(
Object value,
Writer writer,
XmlRpcSerializer builtInSerializer )
throws XmlRpcException, IOException
{
Person person = (Person) value;
// Here you write code that outputs XML-RPC to the writer argument. You can do it
// manually like the built-in serializers do (see http://xmlrpc.svn.sourceforge.net/viewvc/xmlrpc/trunk/source/redstone/xmlrpc/serializers/MapSerializer.java?revision=1&view=markup for an example)
// Another alternative would be to create a HashMap and just copy the values you want from the
// Person object and ask the builtInSerializer to serialize the HashMap. Like below:
Map personMap = new HashMap();
personMap.put("name", person.getName());
….
builtInSerializer.serialize(personMap, writer, builtInSerializer);
}
}
2. The Redstone Library has a built-in Introspecting serializer that kicks in when an unknown object is being serialized. The introspecting serializer will look for all public getter-methods on the object and create the struct from that.
So if your Person class has the public methods getName(), getAge(), getDad(), getMom(), the serializer will create a struct with the keys "name", "age", "dad", "mom" in the message and will serialize the values returned by the getters to the XML-RPC message. Nested objects should work - when serializing the Person getDad() value, a nested struct will be created in the message, and so on.
So you can serialize complete object trees to nested XML-RPC structs using just the built-in Introspecting serializer. Note that it must be a tree, in the sense that you don't have cycles in the object graph.
Alternative 1. above is more flexible since you can name the keys in the struct whatever you want. So you can use key names that match the XML-RPC API you are interfacing with even if the Person objects properties don't inherently match the API.
The reason for implementing a PersonSerializer rather than just manually converting the Person to a HashMap and send directly to the XmlRpcClient is that the serializer is registered with the XmlRpcClient and will be invoked whenever and wherever a Person object is being sent. So you can build an object tree with Person-objects here and there, and even nested as in your case, and the XmlRpcClient will invoke your serializer whever it stumbles upon a Person.
If the XML-RPC server API you are invoking matches 100% with the properties in your Person class, than you can just pass it directly to the XmlRpcClient (given that you have public getters for the values in Person that you want to send). If not, you're best off implementing a PersonSerializer and select exactly what you want from the Person (and you'll have the opportunity to rename keys in the struct and do any transformations you like).
Again, the key thing to realize is that in XML-RPC there's just primitives, structs, and arrays. And the XML-RPC server may not be implemented in Java and it's API should be documented using just primitives, structs (and their keys), and arrays so that any XML-RPC library can be used.
Best Regards,
Greger