I recently had to create an XMLRPC interface to a database, and decided to use Spring to create the objects I needed and inject the dependencies. This allowed some libraries from a Struts 2 project to be used, and saved a bunch of time.
I started by putting the spring jars in my WEB-INF/lib directory, and configuring my WEB-INF/applictionContext.xml, here it is:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans <a href="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd<br />
http://www.springframework.org/schema/util" title="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd<br />
http://www.springframework.org/schema/util">http://www.springframework.org/schema/beans/spring-beans-2.0.xsd<br />
http://...</a> <a href="http://www.springframework.org/schema/util/spring-util-2.0.xsd"<br />
default-autowire="byName"></a></p>
<p>" title="http://www.springframework.org/schema/util/spring-util-2.0.xsd"<br />
default-autowire="byName"></p>
<p>">http://www.springframework.org/schema/util/spring-util-2.0.xsd"<br />
default-... <bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/jdbc.properties"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>com.informix.jdbc.IfxDriver</value></property>
<property name="url"><value>jdbc:informix-sqli://${hostname}:${ifx_port}/proteus:INFORMIXSERVER=${hostname};IFX_LOCK_MODE_WAIT=-1;IFX_ISOLATION_LEVEL=1</value></property>
<property name="username"><value>${username}</value></property>
<property name="password"><value>${password}</value></property>
<property name="poolPreparedStatements"><value>false</value></property>
<property name="maxActive"><value>5</value></property>
<property name="maxIdle"><value>5</value></property>
<property name="maxWait"><value>40000</value></property>
<property name="validationQuery"><value>select first 1 * from operator</value></property>
<property name="removeAbandoned"><value>true</value></property>
<property name="removeAbandonedTimeout"><value>300</value></property>
<property name="logAbandoned"><value>false</value></property>
</bean>
<bean id="personProvider" class="com.secmgmt.beans.picture.four.PPPersonProvider">
</bean>
<bean id="operatorHistoryCreator" class="com.secmgmt.applications.card_access.PPFourOperatorHistory">
</bean>
</beans>That registers the beans I need, and loads the database specific values from /WEB-INF/jdbc.properties.
Now, I configure my web.xml to have the Spring utilities available, and tell them to use the WEB-INF/applicationContext.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext*.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>Then, I used the redstone xmlrpc libraries, and extended their XmlRpcServlet as directed on their website. When that is done, override the init method, and when setting the invocation handlers, use Spring's BeanFactory to get your beans. Here is that code:
public void init( ServletConfig servletConfig ) throws ServletException { super.init( servletConfig ); l.debug("Created the status xmlrpc class"); BeanFactory factory = new XmlWebApplicationContext(); ((org.springframework.web.context.support.AbstractRefreshableWebApplicationContext)factory).setServletContext(servletConfig.getServletContext()); ((org.springframework.web.context.support.AbstractRefreshableWebApplicationContext)factory).refresh(); getXmlRpcServer().addInvocationHandler("ChangeStatus", (IChangeStatus)factory.getBean("changeStatus")); l.debug("Handler set."); }
Then, setup the web.xml to tell it who to use for the XMLRPC servlet, and off you go. Here is the entire web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Security Managment Consulting PP 4.0 XMLRPC</display-name>
<servlet>
<servlet-name>xml-rpc</servlet-name>
<servlet-class>ChangeStatusServlet</servlet-class>
<init-param>
<param-name>streamMessages</param-name>
<param-value>1</param-value>
</init-param>
<init-param> <!-- Optional! Defaults to text/xml and ISO-8859-1 -->
<param-name>contentType</param-name>
<param-value>text/xml; charset=ISO-8859-1</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>xml-rpc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>Once that's done, bingo, Spring for XMLRPC!
Here is my test client, if anyone cares:
#!/usr/bin/python2 import xmlrpclib results = {0: "Success", 1: "Invalid Login", 2: "EID Not Found", 3: "Server Not Primary", 4: "No Change Needed", 5: "Other Error"} try: p = xmlrpclib.ServerProxy("http://192.168.1.15:8080/xmlrpc-status/") print "Server created" print "Ping result: %s" % (p.ChangeStatus.ping()) print "Add 2 + 3 result: %s" % (p.ChangeStatus.add(2, 3)) print "Testing status change, result: %s" % (results[p.ChangeStatus.changeStatus("T3880LL", "test", "test", "ACTIVE")]) except xmlrpclib.Error, v: print "ERROR", v pass print "Done"