The web services stack is helpful for creating and testing your own web service. For example, you might create a web service that performs a variety of unit conversions (such as converting kilograms to pounds and pounds to kilograms). To keep this web service simple, you could confine it to a single class, such as the Converterclass, whose source code is presented in Listing 10-5.
Listing 10-5.Converter.java
// Converter.java package wsdemo;
import javax.jws.WebService;
@WebService
public class Converter {
public double acresToSqMeters (double value) {
return value*4046.8564224; // acres to square meters }
public double sqMetersToAcres (double value) {
return value/4046.8564224; // square meters to acres }
public double lbsToKilos (double value) {
return value*0.45359237; // pounds to kilograms }
public double kilosToLbs (double value) {
return value/0.45359237; // kilograms to pounds }
}
C H A P T E R 1 0 ■ S E C U R I T Y A N D W E B S E R V I C E S 367
Converteris declared publicand annotated with the @WebServiceannotation to iden- tify its publicmethods (which cannot also be static) as web service operations. These operations are available to client programs. Because @WebService-annotated classes are stored in packages, Converteris assigned to the wsdemopackage.
■ Tip Instead of using @WebServiceto identify all of a class’s publicmethods as web service operations, you can selectively identify publicmethods by annotating them with the @WebMethodannotation.
Convertermust be published at a specific address to turn it into an active web service. You can accomplish this task by invoking the javax.xml.ws.EndPointclass’s public static Endpoint publish(String address, Object implementor)method with the web service’s address URI and a Converterinstance as arguments. Listing 10-6 presents the source code to a RunConverterapplication that handles this task.
Listing 10-6.RunConverter.java
// RunConverter.java package wsdemo;
import javax.xml.ws.Endpoint;
public class RunConverter {
public static void main (String [] args) {
// Start the lightweight HTTP server and the Converter Web service.
Endpoint.publish ("http://localhost:8080/WSDemo/Converter", new Converter ());
} }
Before you can invoke RunConverterto start both the lightweight HTTP server and web service, you need to create an appropriate package directory, compile Listings 10-5 and 10-6, and invoke the wsgentool to generate web service artifacts that allow Converter to be deployed as a web service. Complete the following steps to accomplish these tasks:
1. Within the current directory, create a wsdemodirectory that corresponds to the wsdemopackage. The Converter.javaand RunConverter.javasource files must be stored in this directory.
2. Assuming that the directory containing wsdemois the current directory, invoke javac wsdemo/*.javato compile Converter.javaand RunConverter.java. If all goes well, wsdemoshould contain Converter.classand RunConverter.class. If a compiler error occurs, check the source code to make sure it matches Listings 10-5 and 10-6.
3. Assuming that the directory containing wsdemois the current directory, invoke wsgen -cp . wsdemo.Converterto generate web service artifacts. The -cpoption (with the period character argument representing the current directory) is neces- sary to ensure that Converter.classcan be found. The artifacts’ class files and source files are placed in a jaxwssubdirectory of wsdemo.
4. Assuming that the directory containing wsdemois the current directory, invoke java wsdemo.RunConverterto publish the Converterweb service.
After completing these steps, you can verify that Converterhas been published by starting your web browser and entering http://localhost:8080/WSDemo/Converter?wsdl into the browser’s address field. In response, the browser should display the contents of Converter’s WSDL file. Figure 10-1 shows a portion of this file.
Figure 10-1.Converter’s WSDL file provides an XML-based description of this web service.
Because a web service is no fun unless you can try it out, you need to create a client application that connects itself to Converter, obtains a Converterproxy object, and invokes Converter’s methods via this proxy object. Listing 10-7 presents the source code to a sample TestConverterapplication that exercises the unit-conversion web service.
C H A P T E R 1 0 ■ S E C U R I T Y A N D W E B S E R V I C E S 369
Listing 10-7.TestConverter.java
// TestConverter.java import wsdemo.*;
public class TestConverter {
public static void main (String [] args) {
ConverterService service = new ConverterService ();
Converter proxy = service.getConverterPort ();
System.out.println ("2.5 acres = "+proxy.acresToSqMeters (2.5)+
" square meters");
System.out.println ("358 square meters = "+proxy.sqMetersToAcres (358)+
" acres");
System.out.println ("6 pounds = "+proxy.lbsToKilos (6)+" kilograms");
System.out.println ("2.7 kilograms = "+proxy.kilosToLbs (2.7)+
" pounds");
} }
ConverterServiceand the Converterproxy class result from invoking the wsimporttool to generate web service artifacts, which allows Converterto be imported to client pro- grams. Invoking this tool is one of several tasks that you need to take care of in order to interact with this unit-conversion web service. Complete the following steps to accom- plish these tasks:
1. Within the directory that contains wsdemo, create a TestConverterdirectory. The TestConverterdirectory must contain TestConverter.java.
2. Assuming that the TestConverterdirectory is the current directory, invoke wsimport http://localhost:8080/WSDemo/Converter?wsdl. The artifacts’ class files are placed in a wsdemosubdirectory of TestConverter. If you want to keep the artifacts’ source code for later study, include the -keepoption, as in wsimport -keep http://
localhost:8080/WSDemo/Converter?wsdl.
■ Note wsimport’s -keepoption places artifact source code in the same directory as artifact class files.
You can choose another directory for the source code by specifying wsimport’s -soption.
3. Assuming that the TestConverterdirectory is the current directory, invoke javac TestConverter.javato compile this client application’s source code.
4. Assuming that the TestConverterdirectory is the current directory, invoke java TestConverterto interact with the web service. In response, you should observe the following output:
2.5 acres = 10117.141056 square meters 358 square meters = 0.08846372656524519 acres 6 pounds = 2.7215542200000002 kilograms 2.7 kilograms = 5.952481078991695 pounds
However, you might observe a thrown java.net.ConnectionExceptionif the unit- conversion web service is not already running (via RunConverterand the lightweight HTTP server). If this is the case, invoke java wsdemo.RunConverterto publish the Converter web service, making sure the directory containing wsdemois the current directory.