One of the features touted by Magento is the api exposed via both XML-RPC and SOAP. I quickly (and successfully) tested the SOAP interface using the amazingly complete (and free) soapUI. I wanted to use XML-RPC, and decided to build a test client in Java. While trying to build a client, using the apache ws-xmlrpc library, I ran into a roadblock. The initial login and some other calls would work just fine, but some calls such as product.info would always cause an exception, similar to:
Exception in thread "main" org.apache.xmlrpc.client.XmlRpcClientException: Failed to parse servers response: Unknown type: nil
I posted on the magento forum to no success (except to find a few others with the same problem). So I was on my own..
After some research, I determined that the problem (IMHO) is that the Magento api is incorrectly using the nil type in responses. According to the XML-RPC spec, nil is an extended type, and can only be used with a namespace (e.g. ex:nil) — see the data types section on the apache site. But, luckily, the ws-xmlrpc library can be easily extended to provide a work around, and the following solution worked for me.
All you need to do is extend the builtin TypeFactoryImpl class and the assign the client TypeFactory to your custom class. Most of the work by this custom TypeFactory can be done using the super class, so just check for the incorrect nil usage when getting a parser. e.g the TypeFactory I used :
public class MyTypeFactory extends TypeFactoryImpl {
public MyTypeFactory(XmlRpcController pController) {
super(pController);
}
@Override
public TypeParser getParser(XmlRpcStreamConfig pConfig,
NamespaceContextImpl pContext, String pURI, String pLocalName) {
if ("".equals(pURI) && NullSerializer.NIL_TAG.equals(pLocalName)) {
return new NullParser();
} else {
return super.getParser(pConfig, pContext, pURI, pLocalName);
}
}
}
and then created my XmlRpcClient as follows:
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://mymagentoserver.com/api/xmlrpc/"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
client.setTypeFactory(new MyTypeFactory(client));
Notes:
- There is a enabledForExtensions property used by the client (and server) classes, which can be set by XmlRpcConfig:: setEnabledForExtensions(), but that has no effect here since the Magento server is doing it wrong.
- You would use a very similar method if you needed to implement a custom type (if your XML-RPC server defined one), but would need to provide a custom TypeSerializer as well, by overriding the getSerializer() method in MyTypeFactory. There is an example of this on the ws-xmlrpc site in the advanced techniques section.
As usual, your milage may vary.
No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.
Thanks for the workaround. I was surprised to discover that the bug was in Magento or whatever XML-RPC implementation it’s using, since Python’s xmlrpclib communicates with it just fine. I guess a number of implementations must allow the non-standard nil. Ideally, this should be addressed in Magento.
Magento…
Also sollte mal jemand in die Verlegenheit kommen Magento benutzen zu müssen, tut er mir leid. Vom Funktionsumfang her ist hat es so ziemlich alles, was man sich wünschen könnte. Geht es jedoch darum Erweiterungen zu schreiben hört der Spaß auf. D…
Just for clarification: according to the XMLRPC spec, NIL does not exist at all, namespace or not (http://www.xmlrpc.com/spec).
The ex:nil is an extension first added by the Apache lib whereas the ‘nil’ extension was added by another implementation (http://ontosys.com/xml-rpc/extensions.php), long time before that iirc.
So to say that the fault lies on the magento side is a bit arbitrary…
Hello everybody!
I am currently writing a Magento Connector for Java. The goal is to create a free wrapper / library to manage Magento from a Java application. A few parts such as management of products, categories and pictures are already partially finished and can be used.
The latest version (source code and JAR package) can be downloaded from this homepage:
http://www.panticz.de/MagentoConnector
If someone is interested in co-development, please contact my here http://www.panticz.de/contact/.
Greeting
Pawel
Hey,
Thanks for this post, it saved me hours of making my own walkarround
I’m not sure, that this is only magento problem. I’m connectiong from Java (apache .jar) to Python’s XMLRPC WebService and got the same exception.
Anyway, thanks