سؤال

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.

هل كانت مفيدة؟

المحلول

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);
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top