I've got a little problem developing an Android app. I've got a client (running Android), using android-xmlrpc, 开发者_StackOverflow社区that calls some methods on the server (standard Java app), using Apache XML-RPC. Everything runs fine and smoothly, with one exception. When I try to call a method that has a Long type parameter, the server throws out this exception :
21.12.2010 18:54:35 org.apache.xmlrpc.server.XmlRpcErrorLogger log
SEVERE: Failed to parse XML-RPC request: Unknown type: i8
org.apache.xmlrpc.XmlRpcException: Failed to parse XML-RPC request: Unknown type: i8
at org.apache.xmlrpc.server.XmlRpcStreamServer.getRequest(XmlRpcStreamServer.java:71)
at org.apache.xmlrpc.server.XmlRpcStreamServer.execute(XmlRpcStreamServer.java:199)
at org.apache.xmlrpc.webserver.Connection.run(Connection.java:208)
at org.apache.xmlrpc.util.ThreadPool$Poolable$1.run(ThreadPool.java:68)
Caused by: org.xml.sax.SAXParseException: Unknown type: i8
at org.apache.xmlrpc.parser.RecursiveTypeParserImpl.startElement(RecursiveTypeParserImpl.java:122)
at org.apache.xmlrpc.parser.XmlRpcRequestParser.startElement(XmlRpcRequestParser.java:122)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.xmlrpc.server.XmlRpcStreamServer.getRequest(XmlRpcStreamServer.java:65)
... 3 more
Everything should be in order, the EnabledForExtensions flag on the Apache side, as mentioned here , is set like this :
serverConfig.setEnabledForExtensions(true);
What am I doing wrong?
It seems there are two dialects for Long parameters, and the client and server have to agree which to use. Eg on a c++ server you need to call:
myRegistry.setDialect(xmlrpc_dialect_apache)
Or
myRegistry.setDialect(xmlrpc_dialect_i8)
Or a corresonding method on your client/server.
I believe the default is i8.
I found the solution of this problem here: https://ws.apache.org/xmlrpc/advanced.html
I must create own implementation of the TypeFactory, something like this:
public class ExtendedTypeFactoryImpl extends TypeFactoryImpl {
private static final String LONG_XML_TAG_NAME = "i8";
public ExtendedTypeFactoryImpl(XmlRpcController pController) {
super(pController);
}
@Override
public TypeParser getParser(XmlRpcStreamConfig pConfig, NamespaceContextImpl pContext, String pURI, String pLocalName) {
if (LONG_XML_TAG_NAME.equals(pLocalName)) {
return new LongParser();
} else {
return super.getParser(pConfig, pContext, pURI, pLocalName);
}
}
}
Then I must set my type factory of my XMPRPC client:
XmlRpcClient client = new XmlRpcClient();
XmlRpcClientConfigImpl conf = new XmlRpcClientConfigImpl();
conf.setServerURL(url.toURL());
conf.setEncoding(Charsets.UTF_8.name());
conf.setEnabledForExtensions(true);
client.setTypeFactory(new ExtendedTypeFactoryImpl(client));
client.setConfig(conf);
精彩评论