|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 5
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
Based on the above configuration information, whenever Tomcat -- or any J2EE-compliant Web server -- encounters a .jws file in the Axis context (set up above during installation), it will invoke the AxisServlet. The AxisServlet then performs its magic as described above.
Now let's create a simple client that we'll use to test the service. The code to do that is shown here:
package javaworld.axis;
import org.apache.axis.client.ServiceClient;
public class Client1
{
public static void main(String[] args) throws Exception
{
String endpoint = "http://localhost:8080/axis/HelloServer.jws";
ServiceClient client = new ServiceClient(endpoint);
String ret = (String)client.invoke("","sayHelloTo",new Object [] {args[0]});
System.out.println(ret);
}
}
As with Apache SOAP, the client code is a bit more involved than the server code. But it is much simpler than the equivalent Apache SOAP client code, which is also shown below for reference. To understand the code below, please refer to "Clean Up Your Wire Protocol with SOAP, Part 2."
package javaworld.axis
import java.net.URL;
import java.util.Vector;
import org.apache.soap.SOAPException;
import org.apache.soap.Constants;
import org.apache.soap.Fault;
import org.apache.soap.rpc.Call;
import org.apache.soap.rpc.Parameter;
import org.apache.soap.rpc.Response;
public class Client
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://localhost:8080/apache-soap/servlet/rpcrouter");
String name = args[0];
// Build the call.
Call call = new Call();
call.setTargetObjectURI("urn:Hello");
call.setMethodName("sayHelloTo");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
Vector params = new Vector();
params.addElement(new Parameter("name", String.class, name, null));
call.setParams(params);
// Invoke the call.
Response resp = null;
try
{
resp = call.invoke(url, "");
}
catch( SOAPException e )
{
System.err.println("Caught SOAPException (" + e.getFaultCode() + "): " + e.getMessage());
System.exit(-1);
}
// Check the response.
if( !resp.generatedFault() )
{
Parameter ret = resp.getReturnValue();
Object value = ret.getValue();
System.out.println(value);
}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code = " + fault.getFaultCode());
System.out.println (" Fault String = " + fault.getFaultString());
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
It should be obvious that Axis does a much better job shielding the client developer from the details. In the simplest case
(as the one in this article), you need to create only an instance of the class org.apache.axis.client.ServiceClient, which requires the service endpoint as its constructor parameter. The endpoint here is http://localhost:8080/axis/HelloServer.jws, since (1) the Web server is on the same machine as the client; (2) Tomcat by default listens for HTTP requests on port 8080;
and (3) the service is deployed as HelloServer.jws. Finally, you invoke any method on the service by simply calling the invoke() method on the ServiceClient instance. At the very least, invoke() requires both the method's name on the service to invoke, and an Object array of parameters.
To test the service, begin by compiling the client using the following command sequence. Note that axis.jar must be included in the CLASSPATH to successfully compile the client application:
set CLASSPATH=AXIS_HOME\lib\axis.jar javac Client1.java
Start Tomcat if it's not already started. To start Tomcat, run the startup.bat batch file located in TOMCAT_HOME\bin\. Next, run the client application:
set CLASSPATH=C:\dev\;AXIS_HOME\lib\axis.jar;AXIS_HOME\lib\log4j-core.jar java javaworld.axis.Client1 John
This time, in addition to axis.jar, you must also include log4j-core.jar, which is the jar file that contains classes used by axis.jar's classes for logging. Also, C:\dev is the directory containing the javaworld package, so you must include it in the CLASSPATH too.
Deploying the Web service as a .jws file works for simple services such as the one in this article. However, this approach fails to meet most commercial Web
services' flexibility requirements, such as the ability to specify custom type mappings or create handler chains. Instead,
most deployments will probably use deployment files such as the one shown below for our Web service:
<m:deploy xmlns:m="AdminService"> <service name="HelloServer" pivot="RPCDispatcher"> <option name="className" value="javaworld.axis.HelloServer"/> <option name="methodName" value="sayHelloTo"/> </service> </m:deploy>
The deployment XML shown above is fairly simple and does not use or demonstrate any of the advanced features allowed in such deployment files. However, let's say that I wanted to define a logging mechanism in the form of an Axis handler -- handlers follow the Chain of Responsibility design pattern (see Resources). I could do this by simply adding the following section to the deployment file:
<!-- define a logging handler configuration --> <handler name="logger" class="loggers.LogHandler"> <option name="filename" value="HelloServer.log"/> </handler>
As I mentioned earlier, Axis offers a much more flexible and capable deployment process. In the previous section, I illustrated how simple deploying Web services in Axis can be. In this section, I give you a peek into Axis's more flexible and capable aspects.
The configuration above is self-explanatory. I have basically created a new service that uses the class javaworld.axis.HelloServer and exposes the sayHelloTo() method. If I want to expose more methods, I would replace the single sayHelloTo() method name with a space-delimited list of method names. However, don't get too attached to this XML descriptor format: in
Axis's final release, this XML will change to the Axis Web Service Deployment Descriptor (WSDD) format. The same configuration
in WSDD format is shown below for reference:
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="HelloServer" provider="java:RPC">
<parameter name="className" value="javaworld.axis.HelloServer"/>
<parameter name="methodName" value="sayHelloTo"/>
</service>
</deployment>
Note: As of alpha 2, when deploying Web services as a .jws file, you should leave the service class in the default package, i.e., with no package declaration. On the other hand, when
deploying services with a configuration file, as we did above, you should declare an explicit package -- for example, I've
added a package javaworld.axis declaration in HelloServer.java. Following these guidelines will save you many headaches.