Я пытаюсь запустить XML RPC-сервер, используя библиотеки apache xmlrpc (3.1.3).
Я реализовал на этом сервере метод "system.listMethods", как требуется в спецификациях XML RPC (http://xmlrpc.scripting.com/spec).
Чтобы проверить, что этот сервер соответствует спецификациям XML RPC, я сделал клиент, который разрешил мне делать Почтовый запрос на сервер, отправляя XML файл, который я хочу (я пишу его как Sring, а клиент отправляет его).
Затем мой клиент печатает XML-ответ сервера.
Он работает, но когда я отправляю этот запрос:
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
Он возвращает мне этот ответ:
<?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>
Что является "неправильным" в соответствии со спецификацией. Это список моих методов, но их что-то не хватает в структуре. Например, их должно быть:
<value><string>system.listMethods</string></value>
Установлено
<value>system.listMethods</value>
На моем сервере метод "system.listMethods" возвращает объект java типа Object [] (я попытался изменить его на String [], но он не влияет на результат). согласно документации apache (http://ws.apache.org/xmlrpc/types.html), этот тип Java должен быть превращен в массив массивов XML-RCP, который я должен использовать.
Что можно сделать, чтобы мой сервер соответствовал спецификациям XML-RCP?
В этом случае мне нужно только добавить " <string>
" или " </string>
", но, как показано в типе массива спецификаций, я должен иметь возможность смешивать типы данных:
<array>
<data>
<value><i4>12</i4></value>
<value><string>Egypt</string></value>
<value><boolean>0</boolean></value>
<value><i4>-31</i4></value>
</data>
</array>
Поэтому я пытаюсь найти решение, которое позволяет мне это сделать.
Я наконец нашел, как это сделать, поэтому, если кому-то интересно, вот как я это сделал:
Я создал "Пользовательский тип данных", как описано в разделе с таким же именем: http://ws.apache.org/xmlrpc/advanced.html
Мне также пришлось посмотреть на источники org.apache.xmlrpc.serializer.StringSerializer и org.apache.xmlrpc.common.TypeFactoryImpl (найдены на GrepCode здесь: 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)
Мне пришлось создать два класса:
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 (метод для вызова вместо 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);
}
}
}