The problem is typically caused by code like the following:
Integer[] result = server.execute("Server.foo", param);
The problem is in the fact, that the XML-RPC response tells the client, that the server returns an array. It doesn't tell what type the array has. In other words, the client will always receive an object array. The workaround is to use code like the following:
Object[] result = (Integer[])server.execute("Server.foo", param); for (int i = 0; i < result.length; i++) { Integer num = (Integer) result[i]; ... }
[top] |
That's simple: Set the properties "enabledForExtensions" and "gzipCompressing". That said, note the following hints:
[top] |
That's as simple as enabling request compression: Set the properties "enabledForExtensions" and "gzipRequesting". That said, note the following hints:
[top] |
Yes, use the class TimingOutCallback.
// Wait for 10 seconds. TimingOutCallback callback = new TimingOutCallback(10 * 1000); XmlRpcClient client = new XmlRpcClient(url); client.executeAsync(methodName, params, callback); try { return callback.waitForResponse(); } catch (TimeoutException e) { System.out.println("No response from server."); } catch (Exception e) { System.out.println("Server returned an error message."); }
[top] |
You've got to use a special type factory. An example is contained in the documentation on {{{advanced.html}advanced topics}}.
[top] |
You've got to use a special type factory. An example is contained in the documentation on {{{advanced.html}advanced topics}}.
[top] |
Yes, you can. Use the org.apache.xmlrpc.client.XmlRpcSun14HttpTransportFactory. (Or the org.apache.xmlrpc.client.XmlRpcSun15HttpTransportFactory.)
The XmlRpcClient will detect the Java version you are using and automatically create the respective factory. In other words, all you need to do is cast the XmlRpcTransportFactory to the proper class. For example:
XmlRpcClient myClient; XmlRpcTransportFactory factory = myClient.getTransportFactory(); ((XmlRpcSun15HttpTransportFactory) factory).setProxy(String pHost, int pPort);
With the Lite HTTP transport factory, things are slightly different: You have to explicitly create an instance of XmlRpcLite14HttpTransportFactory.
[top] |
[top] |
Set the property "enabledForExtensions". Note, that enabling the streaming mode doesn't mean, that all responses are served in streaming mode. It depends on the clients:
[top] |
Basically you've got to provide an AuthenticationHandler. See the {{{server.html}server documentation}} for an example.
[top] |
The PropertyHandlerMapping assumes, that request processors are POJO's (plain old java objects). However, this is not always desirable. For example, sometimes it is assumed that handlers need to be initialized by the servlet, which is configured through parameters.
The recommended solution is to configure your server with a special request processor factory.
public interface InitializableRequestProcessor { void init(HttpServlet pServlet) throws XmlRpcException; } public class MyXmlRpcServlet extends XmlRpcServlet { protected PropertyHandlerMapping newPropertyHandlerMapping(URL url) throws IOException, XmlRpcException { PropertyHandlerMapping mapping = new PropertyHandlerMapping(); RequestProcessorFactoryFactory factory = new RequestSpecificProcessorFactoryFactory(){ protected Object newRequestProcessor(Class pClass, XmlRpcRequest pRequest) { InitializableRequestProcessor proc = super.newRequestProcessor(pClass, pRequest); proc.init(MyXmlRpcServlet.this); return proc; } }; mapping.setRequestProcessorFactoryFactory(mapping); mapping.load(Thread.currentThread().getContextClassLoader(), url); return mapping; } }
[top] |
That's a similar question than the question on initializing handlers. The main difference is, that in this case you want to initialize the handler with any request. In other words, you might achieve the goal by creating a RequestProcessorFactoryFactory, that provides the necessary details. However, there is an easier solution, which we will demonstrate here: Use a ThreadLocal.
The class ThreadLocal allows to create information at some point in the source code and use this information at one or more completely different and decoupled places. The only assumption is, that you are in the same thread. This is exactly our situation: We create the information when processing of the XML-RPC request starts and read it within the handler.
In the example below, you'd obtain the clients IP address by
writing ClientInfoServlet.getClientIpAddress()
.
public static class ClientInfoServlet extends XmlRpcServlet { private static ThreadLocal clientIpAddress = new ThreadLocal(); public static String getClientIpAddress() { return (String) clientIpAddress.get(); } public void doPost(HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException, ServletException { clientIpAddress.set(pRequest.getRemoteAddr()); super.doPost(pRequest, pResponse); } }
[top] |
[top] |