151
|
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11
|
|
12
|
|
13 <html xmlns="http://www.w3.org/1999/xhtml">
|
|
14 <head>
|
|
15 <title>ws-xmlrpc - The Apache XML-RPC Server</title>
|
|
16 <style type="text/css" media="all">
|
|
17 @import url("./css/maven-base.css");
|
|
18 @import url("./css/maven-theme.css");
|
|
19 @import url("./css/site.css");
|
|
20 </style>
|
|
21 <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
|
|
22 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
|
|
23 </head>
|
|
24 <body class="composite">
|
|
25 <div id="banner">
|
|
26 <a href="" id="bannerLeft">
|
|
27
|
|
28 <img src="images/xmlrpc-logo.gif" alt="" />
|
|
29
|
|
30 </a>
|
|
31 <div class="clear">
|
|
32 <hr/>
|
|
33 </div>
|
|
34 </div>
|
|
35 <div id="breadcrumbs">
|
|
36
|
|
37
|
|
38
|
|
39
|
|
40
|
|
41
|
|
42
|
|
43
|
|
44 <div class="xleft">
|
|
45 Last Published: 2010-02-06
|
|
46 </div>
|
|
47 <div class="xright"> <a href="http://www.apache.org/" class="externalLink">Apache</a>
|
|
48 |
|
|
49 <a href="../">Webservices</a>
|
|
50 |
|
|
51 <a href="">XML-RPC</a>
|
|
52
|
|
53
|
|
54
|
|
55
|
|
56
|
|
57
|
|
58
|
|
59
|
|
60 </div>
|
|
61 <div class="clear">
|
|
62 <hr/>
|
|
63 </div>
|
|
64 </div>
|
|
65 <div id="leftColumn">
|
|
66 <div id="navcolumn">
|
|
67
|
|
68
|
|
69
|
|
70
|
|
71
|
|
72
|
|
73
|
|
74
|
|
75 <h5>XML-RPC</h5>
|
|
76 <ul>
|
|
77
|
|
78 <li class="none">
|
|
79 <a href="index.html">Overview</a>
|
|
80 </li>
|
|
81
|
|
82 <li class="none">
|
|
83 <a href="download.html">Download</a>
|
|
84 </li>
|
|
85
|
|
86 <li class="none">
|
|
87 <a href="changes-report.html">Changes</a>
|
|
88 </li>
|
|
89
|
|
90 <li class="none">
|
|
91 <a href="mail-lists.html">Mailing Lists</a>
|
|
92 </li>
|
|
93
|
|
94 <li class="none">
|
|
95 <a href="contributing.html">Contributing</a>
|
|
96 </li>
|
|
97
|
|
98 <li class="none">
|
|
99 <a href="xmlrpc2">XML-RPC 2</a>
|
|
100 </li>
|
|
101
|
|
102 <li class="none">
|
|
103 <a href="links.html">Links</a>
|
|
104 </li>
|
|
105 </ul>
|
|
106 <h5>Documentation</h5>
|
|
107 <ul>
|
|
108
|
|
109 <li class="none">
|
|
110 <a href="client.html">Client Classes</a>
|
|
111 </li>
|
|
112
|
|
113 <li class="none">
|
|
114 <strong>Server Side XML-RPC</strong>
|
|
115 </li>
|
|
116
|
|
117 <li class="none">
|
|
118 <a href="extensions.html">Vendor Extensions</a>
|
|
119 </li>
|
|
120
|
|
121 <li class="none">
|
|
122 <a href="ssl.html">SSL</a>
|
|
123 </li>
|
|
124
|
|
125 <li class="none">
|
|
126 <a href="introspection.html">Introspection</a>
|
|
127 </li>
|
|
128
|
|
129 <li class="none">
|
|
130 <a href="advanced.html">Advanced Techniques</a>
|
|
131 </li>
|
|
132
|
|
133 <li class="none">
|
|
134 <a href="types.html">XML-RPC Types</a>
|
|
135 </li>
|
|
136
|
|
137 <li class="none">
|
|
138 <a href="faq.html">FAQ</a>
|
|
139 </li>
|
|
140
|
|
141 <li class="none">
|
|
142 <a href="apidocs/index.html">Javadocs</a>
|
|
143 </li>
|
|
144 </ul>
|
|
145 <h5>Project Documentation</h5>
|
|
146 <ul>
|
|
147
|
|
148
|
|
149
|
|
150
|
|
151
|
|
152
|
|
153
|
|
154
|
|
155
|
|
156
|
|
157
|
|
158
|
|
159
|
|
160
|
|
161
|
|
162
|
|
163
|
|
164
|
|
165
|
|
166
|
|
167
|
|
168
|
|
169
|
|
170
|
|
171
|
|
172
|
|
173
|
|
174 <li class="collapsed">
|
|
175 <a href="project-info.html">Project Information</a>
|
|
176 </li>
|
|
177
|
|
178
|
|
179
|
|
180
|
|
181
|
|
182
|
|
183
|
|
184
|
|
185
|
|
186 <li class="collapsed">
|
|
187 <a href="project-reports.html">Project Reports</a>
|
|
188 </li>
|
|
189 </ul>
|
|
190 <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
|
|
191 <img alt="Built by Maven" src="./images/logos/maven-feather.png"></img>
|
|
192 </a>
|
|
193
|
|
194
|
|
195
|
|
196
|
|
197
|
|
198
|
|
199
|
|
200
|
|
201 </div>
|
|
202 </div>
|
|
203 <div id="bodyColumn">
|
|
204 <div id="contentBox">
|
|
205 <div class="section"><h2>Server-side XML-RPC</h2>
|
|
206 <p>If you have read and understood the previous document about the <a href="./client.html">Apache XML-RPC client</a>, then the server isn't too much news.</p>
|
|
207 <p>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 <b>can</b> 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.</p>
|
|
208 <p>Like the XmlRpcClient, the XmlRpcServer needs a configuration, which is given by the XmlRpcServerConfigImpl object.</p>
|
|
209 </div>
|
|
210 <div class="section"><h2>The XML-RPC Servlet</h2>
|
|
211 <p>The easiest way to create an XML-RPC Server is the XmlRpcServlet, which has an automatically embedded instance of XmlRpcServer. This servlet allows you to create a server within 10 minutes or so:</p>
|
|
212 <ol type="1"><li>Create a class, or a set of classes, which are implementing the remote procedure calls. Here's an example of such a class:<div class="source"><pre> package org.apache.xmlrpc.demo;
|
|
213 public class Calculator {
|
|
214 public int add(int i1, int i2) {
|
|
215 return i1 + i2;
|
|
216 }
|
|
217 public int subtract(int i1, int i2) {
|
|
218 return i1 - i2;
|
|
219 }
|
|
220 }
</pre>
|
|
221 </div>
|
|
222 <p>This class has two public, non-static methods, which should be available to the clients.</p>
|
|
223 </li>
|
|
224 <li>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:<div class="source"><pre> Calculator=org.apache.xmlrpc.demo.Calculator
</pre>
|
|
225 </div>
|
|
226 <p>The property file must be called <tt>XmlRpcServlet.properties</tt>, 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.</p>
|
|
227 </li>
|
|
228 <li>Add entries like the following to your war files web.xml:<div class="source"><pre> <servlet>
|
|
229 <servlet-name>XmlRpcServlet</servlet-name>
|
|
230 <servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class>
|
|
231 <init-param>
|
|
232 <param-name>enabledForExtensions</param-name>
|
|
233 <param-value>true</param-value>
|
|
234 <description>
|
|
235 Sets, whether the servlet supports vendor extensions for XML-RPC.
|
|
236 </description>
|
|
237 </init-param>
|
|
238 </servlet>
|
|
239 <servlet-mapping>
|
|
240 <servlet-name>XmlRpcServlet</servlet-name>
|
|
241 <url-pattern>/xmlrpc</url-pattern>
|
|
242 </servlet-mapping>
</pre>
|
|
243 </div>
|
|
244 </li>
|
|
245 </ol>
|
|
246 <p>That's it! You have just created your first XML-RPC server. :-)</p>
|
|
247 </div>
|
|
248 <div class="section"><h2>The Server configuration</h2>
|
|
249 <p>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:</p>
|
|
250 <table class="bodyTable"><tbody><tr class="a"><td align="left">Property Name</td>
|
|
251 <td align="left">Description</td>
|
|
252 </tr>
|
|
253 <tr class="b"><td align="left">enabledForExceptions</td>
|
|
254 <td align="left">If the server catches an exception, and this<br />
|
|
255 property is set, then the server will convert<br />
|
|
256 the exception into a byte array (by using an<br />
|
|
257 ObjectOutputStream) and return the exception to<br />
|
|
258 the client. Note, that this may have privacy<br />
|
|
259 or even security implications, because Exceptions<br />
|
|
260 may contain arbitrary Java objects, which you<br />
|
|
261 possibly do not want to be sent to the client.</td>
|
|
262 </tr>
|
|
263 <tr class="a"><td align="left">enabledForExtensions</td>
|
|
264 <td align="left">Whether the vendor extensions of Apache XML-RPC<br />
|
|
265 should be enabled. By default, Apache XML-RPC is<br />
|
|
266 strictly compliant to the XML-RPC specification.<br />
|
|
267 Enabling this property doesn't indicate, that the<br />
|
|
268 server is unable to serve requests by standard<br />
|
|
269 clients: In contrary, the servers behaviour<br />
|
|
270 depends on the client. Setting this property to<br />
|
|
271 true will only advice the server, that it <b>may</b><br />
|
|
272 accept requests, which ask for vendor extensions.<br />
|
|
273 For example, if a client sends a content-length<br />
|
|
274 header, then the server assumes, that the client<br />
|
|
275 <b>wants</b> a content-length header in the request<br />
|
|
276 and disables the streaming mode.</td>
|
|
277 </tr>
|
|
278 </tbody>
|
|
279 </table>
|
|
280 </div>
|
|
281 <div class="section"><h2>Basic Authentication</h2>
|
|
282 <p>Basic authentication is frequently used to authenticate and authorize users. Within Apache XML-RPC, basic authentication is done by the <a href="apidocs/org/apache/xmlrpc/XmlRpcHandler.html">XmlRpcHandler</a>. The handler receives an instance of <a href="apidocs/org/apache/xmlrpc/XmlRpcRequest.html">XmlRpcRequest</a>. This object has a method <tt>getConfig()</tt>, which returns an instance of <a href="apidocs/org/apache/xmlrpc/XmlRpcRequestConfig.html">XmlRpcRequestConfig</a>.</p>
|
|
283 <p>If you are running within a HTTP server, then the request configuration may be casted to an instance of <a href="apidocs/org/apache/xmlrpc/common/XmlRpcHttpRequestConfig.html">XmlRpcHttpRequestConfig</a>. This object has methods <tt>getBasicUserName()</tt>, and <tt>getBasicPassword()</tt>, which provide the necessary details.</p>
|
|
284 <p>In other words: Your task is to provide your own instance of <a href="apidocs/org/apache/xmlrpc/server/XmlRpcHandlerMapping.html">XmlRpcHandlerMapping</a>, which creates your own handlers. And your own handlers are responsible to validate the basic authentication details.</p>
|
|
285 <p>Here's an example servlet, which overrides the default <a href="apidocs/org/apache/xmlrpc/server/PropertyHandlerMapping.html">PropertyHandlerMapping</a>.</p>
|
|
286 <div class="source"><pre> public class MyServlet extends XmlRpcServlet {
|
|
287 private boolean isAuthenticated(String pUserName, String pPassword) {
|
|
288 return "foo".equals(pUserName) && "bar".equals(pPassword);
|
|
289 }
|
|
290 protected XmlRpcHandlerMapping newXmlRpcHandlerMapping() throws XmlRpcException {
|
|
291 PropertyHandlerMapping mapping
|
|
292 = (PropertyHandlerMapping) super.newXmlRpcHandlerMapping();
|
|
293 AbstractReflectiveHandlerMapping.AuthenticationHandler handler =
|
|
294 new AbstractReflectiveHandlerMapping.AuthenticationHandler(){
|
|
295 public boolean isAuthorized(XmlRpcRequest pRequest){
|
|
296 XmlRpcHttpRequestConfig config =
|
|
297 (XmlRpcHttpRequestConfig) pRequest.getConfig();
|
|
298 return isAuthenticated(config.getBasicUserName(),
|
|
299 config.getBasicPassword());
|
|
300 };
|
|
301 };
|
|
302 mapping.setAuthenticationHandler(handler);
|
|
303 return mapping;
|
|
304 }
|
|
305 }
</pre>
|
|
306 </div>
|
|
307 </div>
|
|
308 <div class="section"><h2>The WebServer class</h2>
|
|
309 <p>The <a href="apidocs/org/apache/xmlrpc/webserver/WebServer.html">WebServer</a> is a minimal HTTP server, that might be used as an embedded web server.</p>
|
|
310 <p>Use of the WebServer has grown very popular amongst users of Apache XML-RPC. Why this is the case, can hardly be explained, because the WebServer is at best a workaround, compared to full blown servlet engines like Tomcat or Jetty. For example, under heavy load it will almost definitely be slower than a real servlet engine, because it does neither support proper keepalive (multiple requests per physical connection) nor chunked mode (in other words, it cannot stream requests).</p>
|
|
311 <p>If you still insist in using the WebServer, it is recommended to use its subclass, the <a href="apidocs/org/apache/xmlrpc/webserver/ServletWebServer.html">ServletWebServer</a> instead, which offers a minimal subset of the servlet API. In other words, you keep yourself the option to migrate to a real servlet engine later.</p>
|
|
312 <p>Use of the WebServer goes roughly like this: First of all, create a property file (for example "MyHandlers.properties") and add it to your jar file. The property keys are handler names and the property values are the handler classes. Once that is done, create an instance of WebServer.</p>
|
|
313 <div class="source"><pre> package org.apache.xmlrpc.demo.webserver;
|
|
314
|
|
315 import java.net.InetAddress;
|
|
316
|
|
317 import org.apache.xmlrpc.common.TypeConverterFactoryImpl;
|
|
318 import org.apache.xmlrpc.demo.webserver.proxy.impls.AdderImpl;
|
|
319 import org.apache.xmlrpc.server.PropertyHandlerMapping;
|
|
320 import org.apache.xmlrpc.server.XmlRpcServer;
|
|
321 import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
|
|
322 import org.apache.xmlrpc.webserver.WebServer;
|
|
323
|
|
324 public class Server {
|
|
325 private static final int port = 8080;
|
|
326
|
|
327 public static void main(String[] args) throws Exception {
|
|
328 WebServer webServer = new WebServer(port);
|
|
329
|
|
330 XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
|
|
331
|
|
332 PropertyHandlerMapping phm = new PropertyHandlerMapping();
|
|
333 /* Load handler definitions from a property file.
|
|
334 * The property file might look like:
|
|
335 * Calculator=org.apache.xmlrpc.demo.Calculator
|
|
336 * org.apache.xmlrpc.demo.proxy.Adder=org.apache.xmlrpc.demo.proxy.AdderImpl
|
|
337 */
|
|
338 phm.load(Thread.currentThread().getContextClassLoader(),
|
|
339 "MyHandlers.properties");
|
|
340
|
|
341 /* You may also provide the handler classes directly,
|
|
342 * like this:
|
|
343 * phm.addHandler("Calculator",
|
|
344 * org.apache.xmlrpc.demo.Calculator.class);
|
|
345 * phm.addHandler(org.apache.xmlrpc.demo.proxy.Adder.class.getName(),
|
|
346 * org.apache.xmlrpc.demo.proxy.AdderImpl.class);
|
|
347 */
|
|
348 xmlRpcServer.setHandlerMapping(phm);
|
|
349
|
|
350 XmlRpcServerConfigImpl serverConfig =
|
|
351 (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
|
|
352 serverConfig.setEnabledForExtensions(true);
|
|
353 serverConfig.setContentLengthOptional(false);
|
|
354
|
|
355 webServer.start();
|
|
356 }
|
|
357 }
</pre>
|
|
358 </div>
|
|
359 <p>The Calculator class can be found above. The Adder and AdderImpl classes can be found in the <a href="advanced.html">proxy example</a>.</p>
|
|
360 <p>Jimisola Laursen, who provided the above example, has also supplied an example for the client:</p>
|
|
361 <div class="source"><pre> package org.apache.xmlrpc.demo.client;
|
|
362
|
|
363 import java.net.MalformedURLException;
|
|
364 import java.net.URL;
|
|
365
|
|
366 import org.apache.xmlrpc.XmlRpcException;
|
|
367 import org.apache.xmlrpc.client.XmlRpcClient;
|
|
368 import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
|
|
369 import org.apache.xmlrpc.client.XmlRpcCommonsTransportFactory;
|
|
370 import org.apache.xmlrpc.client.util.ClientFactory;
|
|
371 import org.apache.xmlrpc.demo.proxy.Adder;
|
|
372
|
|
373 public class Client {
|
|
374 public static void main(String[] args) throws Exception {
|
|
375 // create configuration
|
|
376 XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
|
|
377 config.setServerURL(new URL("http://127.0.0.1:8080/xmlrpc"));
|
|
378 config.setEnabledForExtensions(true);
|
|
379 config.setConnectionTimeout(60 * 1000);
|
|
380 config.setReplyTimeout(60 * 1000);
|
|
381
|
|
382 XmlRpcClient client = new XmlRpcClient();
|
|
383
|
|
384 // use Commons HttpClient as transport
|
|
385 client.setTransportFactory(
|
|
386 new XmlRpcCommonsTransportFactory(client));
|
|
387 // set configuration
|
|
388 client.setConfig(config);
|
|
389
|
|
390 // make the a regular call
|
|
391 Object[] params = new Object[]
|
|
392 { new Integer(2), new Integer(3) };
|
|
393 Integer result = (Integer) client.execute("Calculator.add", params);
|
|
394 System.out.println("2 + 3 = " + result);
|
|
395
|
|
396 // make a call using dynamic proxy
|
|
397 ClientFactory factory = new ClientFactory(client);
|
|
398 Adder adder = (Adder) factory.newInstance(Adder.class);
|
|
399 int sum = adder.add(2, 4);
|
|
400 System.out.println("2 + 4 = " + sum);
|
|
401 }
|
|
402 }
</pre>
|
|
403 </div>
|
|
404 </div>
|
|
405 <div class="section"><h2>The ServletWebServer class</h2>
|
|
406 <p>This is a subclass of the standalone WebServer, which offers a minimal servlet API. It is recommended to use this class, rather than the WebServer, because it offers you a smooth migration path to a full blown servlet engine.</p>
|
|
407 <p>Use of the <a href="apidocs/org/apache/xmlrpc/webserver/ServletWebServer.html">ServletWebServer</a> goes like this: First of all, create a servlet. It may be an instance of <a name="alink_XmlRpcServlet">@link XmlRpcServlet</a> or a subclass thereof. Note, that servlets are stateless: One servlet may be used by multiple threads (aka requests) concurrently. In other words, the servlet must not have any instance variables, other than those which are read only after the servlets initialization.</p>
|
|
408 <p>The XmlRpcServlet is by default using a property file named <tt>org/apache/xmlrpc/server/webserver/XmlRpcServlet.properties</tt>. See the <a href="apidocs/org/apache/xmlrpc/server/PropertyHandlerMapping.html">PropertyHandlerMapping</a> for details on the property file.</p>
|
|
409 <div class="source"><pre> package org.apache.xmlrpc.demo.webserver;
|
|
410
|
|
411 import java.net.InetAddress;
|
|
412
|
|
413 import org.apache.xmlrpc.common.TypeConverterFactoryImpl;
|
|
414 import org.apache.xmlrpc.demo.webserver.proxy.impls.AdderImpl;
|
|
415 import org.apache.xmlrpc.server.PropertyHandlerMapping;
|
|
416 import org.apache.xmlrpc.server.XmlRpcServer;
|
|
417 import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
|
|
418 import org.apache.xmlrpc.webserver.ServletWebServer;
|
|
419
|
|
420 public class ServletServer {
|
|
421 private static final int port = 8080;
|
|
422
|
|
423 public static void main(String[] args) throws Exception {
|
|
424 XmlRpcServlet servlet = new XmlRpcServlet();
|
|
425 ServletWebServer webServer = new ServletWebServer(servlet, port);
|
|
426 webServer.start();
|
|
427 }
|
|
428 }
</pre>
|
|
429 </div>
|
|
430 </div>
|
|
431
|
|
432 </div>
|
|
433 </div>
|
|
434 <div class="clear">
|
|
435 <hr/>
|
|
436 </div>
|
|
437 <div id="footer">
|
|
438 <div class="xright">©
|
|
439 2001-2010
|
|
440
|
|
441 The Apache Software Foundation
|
|
442
|
|
443
|
|
444
|
|
445
|
|
446
|
|
447
|
|
448
|
|
449
|
|
450 </div>
|
|
451 <div class="clear">
|
|
452 <hr/>
|
|
453 </div>
|
|
454 </div>
|
|
455 </body>
|
|
456 </html>
|