Apache XML-RPC 似乎无法解析 android-xmlrpc 传递给它的长类型

Posted

技术标签:

【中文标题】Apache XML-RPC 似乎无法解析 android-xmlrpc 传递给它的长类型【英文标题】:Apache XML-RPC seems unable to parse long type passed to it by android-xmlrpc 【发布时间】:2010-12-21 18:17:43 【问题描述】:

我在开发 android 应用时遇到了一点问题。我有一个使用 android-xmlrpc 的客户端(运行 Android),它使用 Apache XML-RPC 在服务器(标准 Java 应用程序)上调用一些方法。除了一个例外,一切都运行良好且顺利。当我尝试调用具有 Long 类型参数的方法时,服务器会抛出此异常:

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

一切都应该井井有条,Apache 端的 EnabledForExtensions 标志,如 here 所述,设置如下:

serverConfig.setEnabledForExtensions(true);

我做错了什么?

【问题讨论】:

【参考方案1】:

Long 参数似乎有两种方言,客户端和服务器必须同意使用哪个方言。例如,在您需要调用的 c++ 服务器上:

myRegistry.setDialect(xmlrpc_dialect_apache)

或者

myRegistry.setDialect(xmlrpc_dialect_i8)

或者您的客户端/服务器上的相应方法。

我相信默认是 i8。

【讨论】:

C++ 服务器是什么意思?您提供的代码也是用 Java 还是什么?没有足够的上下文来理解您在代码示例中所做的事情【参考方案2】:

我在这里找到了这个问题的解决方案:https://ws.apache.org/xmlrpc/advanced.html

我必须创建自己的 TypeFactory 实现,如下所示:

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);
    


然后我必须设置我的 XMPRPC 客户端的类型工厂:

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);

【讨论】:

以上是关于Apache XML-RPC 似乎无法解析 android-xmlrpc 传递给它的长类型的主要内容,如果未能解决你的问题,请参考以下文章

如何从 PHP 访问 XML-RPC 数据?

使用Groovy和Apache XML-RPC访问SNIPPLR

Apache xml-rpc 客户端和服务器实现

MAMP “无法启动 Apache,因为端口正在使用中。” AND“无法通过 /tmp/mysql.sock 连接到本地 MySQL 服务器

从Minos部署系统谈谈XML-RPC

Spring 不会在 XML-RPC 控制器下初始化服务中的自动装配 DAO bean