Reputation: 61
I am trying to run an XML RPC Server using apache xmlrpc (3.1.3) libraries.
I implemented on this server a method "system.listMethods" as required in the XML RPC specifications (http://xmlrpc.scripting.com/spec).
To check that this server follow the XML RPC specifications , I did a client that enable me to do a Post Request to the server, sending the XML file that I want (I write it as a Sring and the client send it).
Then, my client print the server XML response.
It works, but when I post this Request:
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
It returns me this Response:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
<params>
<param>
<value><array><data>
<value>system.listMethods</value>
<value>system.methodSignature</value>
<value>system.methodHelp</value>
<value>Calculator.add</value>
<value>Calculator.subtract</value>
</data></array></value>
</param>
</params>
</methodResponse>
Which is "wrong" according to the specification. It is the list of my methods, but their is something missing in the structure. For exemple, their should be :
<value><string>system.listMethods</string></value>
Insted of
<value>system.listMethods</value>
In my server, the "system.listMethods" method return a java object of type Object[] (I tried to change it to String[], but it don't affect the result). according to the apache documentation (http://ws.apache.org/xmlrpc/types.html), this java type should be turned into an XML-RCP array type, that I should use.
What can do to make my server follow the XML-RCP specifications?
In this case, I only have to add "<string>
", or "</string>
" somewhere, but as shown in the specification array type exemple, I should be able to mix the data types :
<array>
<data>
<value><i4>12</i4></value>
<value><string>Egypt</string></value>
<value><boolean>0</boolean></value>
<value><i4>-31</i4></value>
</data>
</array>
So I try to find a solution that enables me to do that too.
Upvotes: 3
Views: 1220
Reputation: 61
I finally found how to do it, so if anyone is interested, here is how I did it:
I created a "Custom data type", as described in the section of the same name here: http://ws.apache.org/xmlrpc/advanced.html
I also had to look at the sources of org.apache.xmlrpc.serializer.StringSerializer and org.apache.xmlrpc.common.TypeFactoryImpl (found on GrepCode here: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.xmlrpc/xmlrpc-common/3.1.3/org/apache/xmlrpc/common/TypeFactoryImpl.java#TypeFactoryImpl.0STRING_SERIALIZER)
I had to create two class:
MyStringSerializer:
import org.apache.xmlrpc.serializer.*;<br>
import org.xml.sax.ContentHandler;<br>
import org.xml.sax.SAXException;
public class MyStringSerializer extends TypeSerializerImpl {
// Tag name of an string.
public static final String STRING_TAG = "string";
public void write(ContentHandler pHandler, Object pObject) throws SAXException {
write(pHandler, STRING_TAG, pObject.toString());
}
}
MyTypeFactory (methode to call instead of TypeFactoryImpl):
import org.apache.xmlrpc.common.TypeFactoryImpl;<br>
import org.apache.xmlrpc.common.XmlRpcController;<br>
import org.apache.xmlrpc.common.XmlRpcStreamConfig;<br>
import org.apache.xmlrpc.serializer.TypeSerializer;<br>
import org.xml.sax.SAXException;<br>
public class MyTypeFactory extends TypeFactoryImpl {
public MyTypeFactory(XmlRpcController pController) {
super(pController);
}
public TypeSerializer getSerializer(XmlRpcStreamConfig pConfig, Object pObject) throws SAXException {
if (pObject instanceof String){
return new MyStringSerializer();
}else{
return super.getSerializer(pConfig, pObject);
}
}
}
Upvotes: 3