Apache XML-RPC 3 with Spring Controllers

XML-RPC is a nice, simple remoting protocol that involves little excess configuration. In a project I own, there was a requirement for a trivial remoting protocol and XML-RPC fit the bill nicely. A staple of my projects is usually the Spring Framework, and in this case, the XML-RPC solution should fit elegantly into my existing project infrastructure. I selected Apache XML-RPC 3.0 for its maturity of code.

However, in its out-of-the-package form, Apache XML-RPC is incompatible for working with Spring and needs to have some plumbing created in order for it to drop in nicely.

There is an article by Dejan Bosanac at the ONJava Blog that claims to work with Apache XML-RPC 3.0, but it does not. I had to make my own solution.

In order to integrate with Spring, several components need to be created, and I document them below. The first order of business is the Spring MVC controller. The other pieces subclass components from Apache's implementation to allow us the behavior we require when used with Spring. Finally, I tie this all together with an example applicationContext.xml configuration file.

Comments: 6

#6 Tomas Salfischberger wrote on Monday, April 7, 2008 at 6:41 AM

I like your approach altough I've taken a little bit different route to eliminate the need to specify a separate handler and mapping to be able to specify configuration like this:

<bean id="xmlRpcHandlerMapping" class="nl.celerity.example.xmlrpc.SimpleHandlerMapping">
    <property name="services">
        <map>
            <entry key="ExampleService" value-ref="exampleService" />
            <entry key="OtherService" value-ref="otherService" />
        </map>
    </property>
</bean>

<bean id="xmlRpcController" class="nl.celerity.example.xmlrpc.XmlRpcController">
    <property name="mapping" ref="xmlRpcHandlerMapping" />
</bean>

You can check out what I did to change this at: http://www.celerity.nl/blog/2008/03/exporting-springbeans-with-xml-rpc/

#5 Authenticated User Perry Nguyen wrote on Tuesday, November 21, 2006 at 5:59 PM

Rapthor,

This post is about how to run Apache-WS XML-RPC as a server-side service with Spring, not how to connect to XML-RPC using Apache-WS XML-RPC as a client.

You should refer to the instructions that are listed at their homepage: http://ws.apache.org/xmlrpc/client.html

#4 Rapthor wrote on Friday, November 17, 2006 at 8:21 AM

"You can now call your service as aService.hello() at the URL you have configured in your webapp."

What do you mean by that? How do I call this method from a client?

	XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
	config.setServerURL(new URL("http://127.0.0.1:8080/epadmin/call.rpccommand"));
	config.setBasicUserName("test");
	config.setBasicPassword("test");
			
	XmlRpcClient client = new XmlRpcClient();
	client.setTransportFactory(new XmlRpcCommonsTransportFactory(client));			
	client.setConfig(config);

..... what now?

#3 Francisco Lozano wrote on Monday, October 23, 2006 at 12:55 PM

I think it doesnt, and it just provides you the class of the handler you have to instantiate!!! it's weird.

#2 Authenticated User Perry Nguyen wrote on Tuesday, October 17, 2006 at 2:29 PM

Francisco,

You're right. The way that Apache-WS XML-RPC is designed seems to make it that it favors only one instance/handler per interface. Some trickery could be done to allow swapping of which implementation to use in the ProcessorFactoryFactory interface.

Effectively, one could inspect the Handler name being used, as you mention "premium" or "standard" and return a different bean instead. Rather than using the StatelessProcessorFactoryFactory interface, you can instead use RequestSpecificProcessorFactoryFactory which also receives an XmlRpcRequest in the call to getRequestProcessor().

If I'm guessing correctly, XmlRpcRequest#getMethodName() will hopefully include the Handler name which will allow you to select which bean to return.

#1 Francisco Lozano wrote on Sunday, October 15, 2006 at 9:47 AM

Hello, Your approach is great, thanks for your code and such detailed instructions.

I think that with Apache's XML-RPC 3.0 it has become much more dificult to use managed beans as handlers. In old XMLRPC you could just .addHandle what you wanted. With your approach you partially solve this, but not always: Imagine you have a public interface MyService { public void doSomething(); }

You have just one implementation:

public class MyServiceImpl { private String name; public String getName { ... } public void setName(String name}{ ... } public void doSomething() { System.out.println("Hello this is "+getName() ); }

}

Imagine you'd like to use MyServiceImpl in two different services but in the same server, so that you can do, for example, standard.doSomething() and premium.doSomething().

Using your approach you couldn't have two different instances of the same service handled by different spring-managed beans.

It would be great if apache made doing such simple things easier, like they were in the past.

Comment

No HTML is allowed. Numeric entity refs (&#nnnn;) are supported. Use {{{ and }}} to delimited preformatted sections. Items noted by * are mandatory.

Identify yourself

All new comments are moderated for spam protection. Email addresses are visible only to the entry owner and administrators.

  • Use AccessKey-P to Preview and AccessKey-S to Post