if ( !cl.isFaultResponse() )
{
System.out.println( retVal.toString );
}
}
catch ( XmlRpcException e )
{
e.printStackTrace();
}
}
}
I think that should work. You'll have to change the path though to where you're servlet is responding. Using the speller handler with the following invoke() call:
cl.invoke(
"Speller.speller.spellCheck",
new Object[] {
"The text to spel check",
new Hashtable() } );
This may be somewhat harder to understand compared to the Echo handler, as the Speller handler is an XmlRpcClient relaying the call to www.stuffeddog.com. Check the documentation for clarification.
One more thing. As the speller call needs to be able to serialize a Hashtable() you have to call XmlRpcSerializer.registerCustomSerializer(
new HashtableSerializer() ); before doing the invoke() call.
I have no JDK around to verify this, and if you didn't follow, send me a mail to greger.ohlson@marquee.se and I'll setup a complete example for you.
Have a nice day!
Greger
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2001-06-12
Thanks for your quick response, Greger. I could connect to the Servlet server, but I got an error:
Result was {faultString=marquee.xmlrpc.XmlRpcException: The method cannot be found., faultCode=-1}
// 1) Register the serializers we need
XmlRpcSerializer.registerCustomSerializer(new HashtableSerializer());
// 2) Create the client
XmlRpcClient client = new XmlRpcClient("devlab09", 8080, "/examples/servlet/ServletExample");
//XmlRpcClient client = new XmlRpcClient("www.stuffeddog.com", 80, "/speller/speller-rpc.cgi");
Hashtable response;
response = new Hashtable();
try{
// 3) Invoke a method.
response = (Hashtable) client.invoke("Echo.echo", new Object[] {"Hello xmlrpc!"});
//response = (Hashtable) client.invoke("Speller.speller.spellCheck", new Object[] {"Hello xmlrpc!", new Hashtable()});
if ( !client.isFaultResponse() )
{
System.out.println( response.toString());
return;
}
}
catch ( XmlRpcException e )
{
e.printStackTrace();
return;
}
// The method retuned. String.endsWith() returns a boolean,
// so be sure to cast the result accordingly.
String result = response.toString();
// Print the result of the method call.
System.err.println("Result was " + result);
/**
* Simple invocation handler with a single echo method.
*/
class EchoInvocationHandler extends ReflectiveInvocationHandler
{
/**
* Sample method returning the single argument. The argument for obj may be of any type
* supported by the built-in serializer, or it may be a struct (Hashtable) or an array
* (Vector). To support these composite types while serializing the response, a
* VectorSerializer and a HashTableSerializer are registered in ServletExample.init() below.
*
* @param obj The object sent over XML-RPC.
*
* @return The object received in obj. This may be any of the built-in types, or a hashtable
* or a struct.
*/
/**
* A simple servlet example with two invocation handlers; en Echo handler and an XmlRpcClient
* hooked up to the spellchecking service. This shows a nice feature introduced by Hannes
* Walnffer in the Helma XML-RPC Library -- XmlRpcClients may also serve as InvocationHandlers.
* How is this? XmlRpcClients have an invoke() method that you call when you want the client
* object to invoke a method on the server the client is connected to. Invocation handlers also
* has an invoke() method that the XmlRpcServer (a dispatcher actually) calls when an inbound
* call to that handler is received.<p>
*
* By chance (oh, really?) the two invoke() methods have the same signature. By registering
* an XmlRpcClient as an invocation handler, when the server receives a call to that handler,
* it calls its invoke() method as it does with all handlers. The invoke() method of the client,
* as I explained, in turn calls the server for which it was created. We have created a kind of
* relay that is very useful when an applet is performing XML-RPC invocations on the server it
* was loaded from. Applets may only communicate with the server it originated from, but if that
* server has registered an XmlRpcClient as an invocation handler, that client will act as a
* relay to another XML-RPC service.<p>
*
* The sample servlet registers an XmlRpcClient under the name "Speller", which is hooked up
* to the spelling service at stuffeddog.com. Invoking the "Speller.invoke" method on this
* servlet, will make the client autmatically relay the call to the stuffeddog server and
* back to the caller. Fancy stuff. The first argument to the "Speller.invoke" method must
* be the method name to call at stuffed dog. This is true when calling all clients acting as
* relays. The second argument is the text to check the spelling for (a string), and the final
* argument should be a Hashtable containing settings for the spell checker. An empty Hashtable
* should be used (it does not support settings yet).<p>
*
* This is an extension to a sample servlet posted by David Watson at SourceForge. Thanks!
*
* @author David Watson (davidthewatson@users.sourceforge.net)
* @author Greger Ohlson (greger.ohlson@marquee.se)
* @version $Revision: 1.1 $
*/
public class ServletExample extends HttpServlet
{
/**
* <describe>
*/
public void init(
ServletConfig config ) throws ServletException
{
XmlRpcParser.setDriver( "com.sun.xml.parser.Parser" );
XmlRpcSerializer.registerCustomSerializer( new VectorSerializer() );
XmlRpcSerializer.registerCustomSerializer( new HashtableSerializer() );
server = new XmlRpcServer ();
server.registerInvocationHandler( "Echo", new EchoInvocationHandler() );
server.registerInvocationHandler( "Speller", new XmlRpcClient(
"www.stuffeddog.com",
80, "/speller/speller-rpc.cgi" ) );
}
/**
* This is your standard handy dandy doPost() as it could appear in any servlet using
* an XmlRpcServer. It's not specific to this example. The exception handling leaves
* a lot to imagination, though.
*/
public void doPost(
HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException
{
try
{
// Note. Wrapping the stream in a ServerInputStream is perhaps the responsibility
// of the server? For now, some implementations must do like below to prevent
// the server from freezing as a result of not recognizing the EOF.
/*
File tempFile = new File("hellojsp.txt");
FileWriter out = new FileWriter(tempFile);
InputStream in = req.getInputStream();
int len = req.getContentLength();
for (int i=0; i < len; i++)
out.write(in.read());
out.flush();
out.close();
*/
byte[] result = server.execute(
new ServerInputStream(
req.getInputStream(),
req.getContentLength() ) );
/*
File tempFile = new File("hellojspout.txt");
FileWriter out = new FileWriter(tempFile);
String temp = new String(result);
Hi,
I'm a newbie to xmlrpc. I set up your servlet sample on my tomcat. Could you give me some client example on how to test it? Thanks in advance,
Julia
Hi Julia!
Using the Echo-handler of the servlet sample could be done with the following (untested) code:
import marquee.xmlrpc.*;
public class XmlRpcTester
{
public static void main( String[] args )
{
XmlRpcClient cl = new XmlRpcClient(
"127.0.0.1", // The computer hosting Tomcat
80,
"/thePath/toTheServlet" );
try
{
Object retVal =
cl.invoke( "Echo.echo", new Object[] { "Echo me!!" } );
if ( !cl.isFaultResponse() )
{
System.out.println( retVal.toString );
}
}
catch ( XmlRpcException e )
{
e.printStackTrace();
}
}
}
I think that should work. You'll have to change the path though to where you're servlet is responding. Using the speller handler with the following invoke() call:
cl.invoke(
"Speller.speller.spellCheck",
new Object[] {
"The text to spel check",
new Hashtable() } );
This may be somewhat harder to understand compared to the Echo handler, as the Speller handler is an XmlRpcClient relaying the call to www.stuffeddog.com. Check the documentation for clarification.
One more thing. As the speller call needs to be able to serialize a Hashtable() you have to call XmlRpcSerializer.registerCustomSerializer(
new HashtableSerializer() ); before doing the invoke() call.
I have no JDK around to verify this, and if you didn't follow, send me a mail to greger.ohlson@marquee.se and I'll setup a complete example for you.
Have a nice day!
Greger
Thanks for your quick response, Greger. I could connect to the Servlet server, but I got an error:
Result was {faultString=marquee.xmlrpc.XmlRpcException: The method cannot be found., faultCode=-1}
Here is my client and server code:
/**
*
* Client.java
*
*/
import marquee.xmlrpc.*;
import marquee.xmlrpc.serializers.*;
import java.util.*;
public class Client {
public static void main(String[] args) {
// 1) Register the serializers we need
XmlRpcSerializer.registerCustomSerializer(new HashtableSerializer());
// 2) Create the client
XmlRpcClient client = new XmlRpcClient("devlab09", 8080, "/examples/servlet/ServletExample");
//XmlRpcClient client = new XmlRpcClient("www.stuffeddog.com", 80, "/speller/speller-rpc.cgi");
Hashtable response;
response = new Hashtable();
try{
// 3) Invoke a method.
response = (Hashtable) client.invoke("Echo.echo", new Object[] {"Hello xmlrpc!"});
//response = (Hashtable) client.invoke("Speller.speller.spellCheck", new Object[] {"Hello xmlrpc!", new Hashtable()});
if ( !client.isFaultResponse() )
{
System.out.println( response.toString());
return;
}
}
catch ( XmlRpcException e )
{
e.printStackTrace();
return;
}
// The method retuned. String.endsWith() returns a boolean,
// so be sure to cast the result accordingly.
String result = response.toString();
// Print the result of the method call.
System.err.println("Result was " + result);
// Done!
}
}
/*
*Server
*/
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.Vector;
import marquee.xmlrpc.*;
import marquee.xmlrpc.serializers.*;
import marquee.xmlrpc.handlers.*;
import marquee.xmlrpc.util.*;
import java.io.File;
import java.io.InputStream;
import java.io.FileWriter;
/**
* Simple invocation handler with a single echo method.
*/
class EchoInvocationHandler extends ReflectiveInvocationHandler
{
/**
* Sample method returning the single argument. The argument for obj may be of any type
* supported by the built-in serializer, or it may be a struct (Hashtable) or an array
* (Vector). To support these composite types while serializing the response, a
* VectorSerializer and a HashTableSerializer are registered in ServletExample.init() below.
*
* @param obj The object sent over XML-RPC.
*
* @return The object received in obj. This may be any of the built-in types, or a hashtable
* or a struct.
*/
public Object echo( Object obj )
{
return obj;
}
}
/**
* A simple servlet example with two invocation handlers; en Echo handler and an XmlRpcClient
* hooked up to the spellchecking service. This shows a nice feature introduced by Hannes
* Walnffer in the Helma XML-RPC Library -- XmlRpcClients may also serve as InvocationHandlers.
* How is this? XmlRpcClients have an invoke() method that you call when you want the client
* object to invoke a method on the server the client is connected to. Invocation handlers also
* has an invoke() method that the XmlRpcServer (a dispatcher actually) calls when an inbound
* call to that handler is received.<p>
*
* By chance (oh, really?) the two invoke() methods have the same signature. By registering
* an XmlRpcClient as an invocation handler, when the server receives a call to that handler,
* it calls its invoke() method as it does with all handlers. The invoke() method of the client,
* as I explained, in turn calls the server for which it was created. We have created a kind of
* relay that is very useful when an applet is performing XML-RPC invocations on the server it
* was loaded from. Applets may only communicate with the server it originated from, but if that
* server has registered an XmlRpcClient as an invocation handler, that client will act as a
* relay to another XML-RPC service.<p>
*
* The sample servlet registers an XmlRpcClient under the name "Speller", which is hooked up
* to the spelling service at stuffeddog.com. Invoking the "Speller.invoke" method on this
* servlet, will make the client autmatically relay the call to the stuffeddog server and
* back to the caller. Fancy stuff. The first argument to the "Speller.invoke" method must
* be the method name to call at stuffed dog. This is true when calling all clients acting as
* relays. The second argument is the text to check the spelling for (a string), and the final
* argument should be a Hashtable containing settings for the spell checker. An empty Hashtable
* should be used (it does not support settings yet).<p>
*
* This is an extension to a sample servlet posted by David Watson at SourceForge. Thanks!
*
* @author David Watson (davidthewatson@users.sourceforge.net)
* @author Greger Ohlson (greger.ohlson@marquee.se)
* @version $Revision: 1.1 $
*/
public class ServletExample extends HttpServlet
{
/**
* <describe>
*/
public void init(
ServletConfig config ) throws ServletException
{
XmlRpcParser.setDriver( "com.sun.xml.parser.Parser" );
XmlRpcSerializer.registerCustomSerializer( new VectorSerializer() );
XmlRpcSerializer.registerCustomSerializer( new HashtableSerializer() );
server = new XmlRpcServer ();
server.registerInvocationHandler( "Echo", new EchoInvocationHandler() );
server.registerInvocationHandler( "Speller", new XmlRpcClient(
"www.stuffeddog.com",
80, "/speller/speller-rpc.cgi" ) );
}
/**
* This is your standard handy dandy doPost() as it could appear in any servlet using
* an XmlRpcServer. It's not specific to this example. The exception handling leaves
* a lot to imagination, though.
*/
public void doPost(
HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException
{
try
{
// Note. Wrapping the stream in a ServerInputStream is perhaps the responsibility
// of the server? For now, some implementations must do like below to prevent
// the server from freezing as a result of not recognizing the EOF.
/*
File tempFile = new File("hellojsp.txt");
FileWriter out = new FileWriter(tempFile);
InputStream in = req.getInputStream();
int len = req.getContentLength();
for (int i=0; i < len; i++)
out.write(in.read());
out.flush();
out.close();
*/
byte[] result = server.execute(
new ServerInputStream(
req.getInputStream(),
req.getContentLength() ) );
/*
File tempFile = new File("hellojspout.txt");
FileWriter out = new FileWriter(tempFile);
String temp = new String(result);
out.write(temp);
out.flush();
out.close();
*/
//res.setContentType( "text/html" );
res.setContentType( "text/xml" );
res.setContentLength( result.length );
OutputStream output = res.getOutputStream();
output.write( result );
//PrintWriter output = res.getWriter();
//output.write( "<html><body>");
//output.write( "Hello XMLRPC!");
//output.write( "</body></html>");
output.flush();
}
catch( java.lang.Throwable e )
{
System.out.println( e );
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doPost(request, response);
}
private XmlRpcServer server;
}