------------------------- The Apache XML-RPC Server ------------------------- Server-side XML-RPC If you have read and understood the previous document about the {{{./client.html}Apache XML-RPC client}}, then the server isn't too much news. First of all, there is an object, called the XmlRpcServer. This objects purpose is to receive and execute XML-RPC calls by the clients. The XmlRpcServer <> be embedded into a servlet container, or another HTTP server (for example, the minimal web server, that comes with XML-RPC), but it doesn't need to. Take the local transport as an example: In that case the XML-RPC server is simply embedded into the client application. Like the XmlRpcClient, the XmlRpcServer needs a configuration, which is given by the XmlRpcServerConfigImpl object. The XML-RPC Servlet The easiest of creating an XML-RPC Server is the XmlRpcServlet. This servlet allows you to create a server within 10 minutes or so: [[1]] Create a class, or a set of classes, which are implementing the remote procedure calls. Here's an example of such a class: ----------------------------------------------------------------------------------- package org.apache.xmlrpc.demo; public class Calculator { public int add(int i1, int i2) { return i1 + i2; } public int subtract(int i1, int i2) { return i1 - i2; } } ----------------------------------------------------------------------------------- This class has two public, non-static methods, which should be available to the clients. The only important thing to consider is: The class must be stateless. In other words, it must not contain any non-final fields. (The same restriction applies, for example, to servlet classes.) [[2]] Create a property file, which contains at least one property. The property name is arbitrary, and the property value is the fully qualified name of the Calculator class. For example, like that: ----------------------------------------------------------------------------------- Calculator=org.apache.xmlrpc.demo.Calculator ----------------------------------------------------------------------------------- The property file must be called <<>>, and it must be located in the package org.apache.xmlrpc.webserver. In other words, you would typically put it into the directory org/apache/xmlrpc/webserver and add it to your jar file. [[3]] Add entries like the following to your war files web.xml: ----------------------------------------------------------------------------------- XmlRpcServlet org.apache.xmlrpc.webserver.XmlRpcServlet enabledForExtensions true Sets, whether the servlet supports vendor extensions for XML-RPC. XmlRpcServlet /xmlrpc ----------------------------------------------------------------------------------- That's it! You have just created your first XML-RPC server. :-) The Server configuration Unlike in the case of the clients configuration, there isn't much to configure on the server. The reason is, that most things depend on the client and the HTTP headers, which are received by the client. There is one very important property to configure, though: *-----------------------+---------------------------------------------------+ | Property Name | Description | *-----------------------+---------------------------------------------------+ | enabledForExtensions | Whether the vendor extensions of Apache XML-RPC | | | should be enabled. By default, Apache XML-RPC is | | | strictly compliant to the XML-RPC specification. | | | | | | Enabling this property doesn't indicate, that the | | | server is unable to serve requests by standard | | | clients: In contrary, the servers behaviour | | | depends on the client. Setting this property to | | | true will only advice the server, that it <> | | | accept requests, which ask for vendor extensions. | | | | | | For example, if a client sends a content-length | | | header, then the server assumes, that the client | | | <> a content-length header in the request | | | and disables the streaming mode. | *-----------------------+---------------------------------------------------+ Basic Authentication Basic authentication is frequently used to authenticate and authorize users. Within Apache XML-RPC, basic authentication is done by the {{{apidocs/org/apache/xmlrpc/XmlRpcHandler.html}XmlRpcHandler}}. The handler receives an instance of {{{apidocs/org/apache/xmlrpc/XmlRpcRequest.html}XmlRpcRequest}}. This object has a method <<>>, which returns an instance of {{{apidocs/org/apache/xmlrpc/XmlRpcRequestConfig.html}XmlRpcRequestConfig}}. If you are running within a HTTP server, then the request configuration may be casted to an instance of {{{apidocs/org/apache/xmlrpc/common/XmlRpcHttpRequestConfig.html}XmlRpcHttpRequestConfig}}. This object has methods <<>>, and <<>>, which provide the necessary details. In other words: Your task is to provide your own instance of {{{apidocs/org/apache/xmlrpc/server/XmlRpcHandlerMapping.html}XmlRpcHandlerMapping}}, which creates your own handlers. And your own handlers are responsible to validate the basic authentication details. Here's an example servlet, which overrides the default {{{apidocs/org/apache/xmlrpc/server/PropertyHandlerMapping.html}PropertyHandlerMapping}}. ----------------------------------------------------------------------------------- public class MyServlet extends PropertyHandlerMapping { private boolean isAuthenticated(String pUserName, String pPassword) { return "foo".equals(pUserName) && "bar".equals(pPassword); } protected XmlRpcHandlerMapping newXmlRpcHandlerMapping() throws XmlRpcException { PropertyHandlerMapping mapping = (PropertyHandlerMapping) super.newXmlRpcHandlerMapping(); PropertyHandlerMapping.AuthenticationHandler handler = new PropertyHandlerMapping.AuthenticationHandler(){ public boolean isAuthorized(XmlRpcRequest pRequest){ XmlRpcHttpRequestConfig config = (XmlRpcHttpRequestConfig) pRequest.getConfig(); return isAuthenticated(config.getBasicUserName(), config.getBasicPassword()); }; }; mapping.setAuthenticationHandler(handler); return mapping; } } -----------------------------------------------------------------------------------