What You Need |
The latest version of Java 5 Tomcat (5.5 or later) Ant (1.6 or later) JAX-WS |
Figure 1. JAX-WS High-Level Architecture |
What is the JAX-WS? Essentially, it consists of the following four things:
Clearly, JAX-WS is more than just an API for building Web services. Figure 1 shows its high-level architecture.
Figure 2. JAX-WS: How It Works |
On the client side, the only Java file the developer supplies is the client class itself. The interface and JavaBeans are generated automatically by wsimport. On the server side, the only Java file the developer supplies is the service implementation. The JavaBeans are generated by apt, and the servlet is part of the JAX-WS library.
The generated JavaBeans (also known as a type of portable artifact) are responsible for marshaling/unmarshaling method invocations and responses, as well as service-specific exceptions. Marshaling and unmarshaling are the transformation from XML to Java objects and back using JAXB. Two JavaBeans are generated for each method in the Web service. One bean is for invoking the method and the other for handling the response. An additional JavaBean is generated for each service-specific exception. (JAX-WS 2.0 Beta User's Guide 3.1.1.1 Generate Portable Artifacts)
<!---->
|
To complete the examples, begin by downloading and unzipping the latest version of Java 5, Tomcat (5.5 or later), Ant (1.6 or later), JAX-WS, and the example code for this article. If you use Java 6, be sure to use a compatible version of Tomcat, Ant, and JAX-WS. These examples will not work using Java 6, Tomcat 5, and JAX-WS RC3 because of library incompatibilities.
Open the build.xml file in the examples directory and set the values of the properties jaxws.home, java.home, and tomcat.home to the root directories of those downloads. Now, open a command prompt and run the following ant targets:
<!---->
|
Figure 3. The Development Process for the Web Service |
Notice in Figure 3 that SimpleMethod.java and SimpleMethodResopnse.java are the JavaBeans responsible for marshaling/unmarshaling the invocation and response. Notice also that the developer inputs only three files; the remaining components are generated by apt and the servlet container. The servlet container generates the WSDL and schema at the time of deployment, which is a change from JAX-RPC. These files are therefore not bundled in the WAR.
SimpleJAXWS.java (see Listing 1) is the same as a non-Web service class definition except for the @WebService annotation:
@WebService public class SimpleJAXWS { public int simpleMethod(int number1, int number2) throws SimpleException { if ( number2 == 0 ) { throw new SimpleException("Cannot divide by zero!", "Numbers: " + number1 + ", " + number2); } return number1 / number2; } }
The sun-jaxws.xml file (see Listing 2) designates the URL for the service endpoint implementation:
<endpoint name='simpleexample' implementation='simpleexample.server.SimpleJAXWS' url-pattern='/simplemethod'/> </endpoints>
The web.xml (see Listing 3) file assigns the WSServlet to the Web service's URL:
<web-app> <servlet> <servlet-name>simpleexample</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>simpleexample</servlet-name> <url-pattern>/simplemethod</url-pattern> </servlet-mapping> </web-app>
The URL http://localhost:8080/jaxws-simpleexample/simplemethod?wsdl shows the definition for the simpleMethod message:
<definitions targetNamespace="http://server.simpleexample/" name="SimpleJAXWSService"> <message name="simpleMethod"> <part element="tns:simpleMethod" name="parameters"/> </message>
The URL http://localhost:8080/jaxws-simpleexample/simplemethod?xsd=1 shows the simple method and it's parameters:
<xs:element type="ns1:simpleMethod" name="simpleMethod"/> <xs:complexType name="simpleMethod"> <xs:sequence> <xs:element type="xs:int" name="arg0"/> <xs:element type="xs:int" name="arg1"/> </xs:sequence> </xs:complexType>
Figure 4 diagrams the basic development process on the client side.
Figure 4. The Development Process for the Client |
Notice in Figure 4 that the developer inputs only three files; the remaining components are generated by wsimport. The other files required by wsimport are the WSDL and schema generated by the servlet container at time of deployment. This is why it's important to wait for Tomcat to completely deploy the Web service before building the client.
The wsimport-generated files can be found in the build/classes/simpleexample/client directory of the example's home. SimpleMethod.java and SimpleMethodResopnse.java are the JavaBeans that marshal/unmarshal the invocation and response. Because package-level annotations are declared in their own .java file, @XMLSchema is found in package-info.java. The annotation maps the client package name to an XML namespace. ObjectFactory.java uses the class-level annotation @XMLRegistry to indicate it will be an XML registry with the factory methods for the client's JavaBeans and their XML equivalents. Other JavaBeans not shown in Figure 4 are generated for handling the exception used by the service.
SimpleMethodClient.java (Listing 4) has a main method that instantiates the SimpleJAXWS Web service object and calls its method. The SimpleJAXWS object is treated the same as a non-webservice object once it has been instantiated:
SimpleJAXWS port = new SimpleJAXWSService().getSimpleJAXWSPort(); double result = port.simpleMethod ( 20, 10 );
The build.properties file (Listing 5) designates the SEI and client class, the client's bindings for its WSDL and schema:
# service endpoint implementation class sei=simpleexample.server.SimpleMethod # customization files client.binding=custom-client.xml, custom-schema.xml server.binding= client.wsdl=http://localhost:8080/jaxws-simpleexample/simplemethod?wsdl client=simpleexample.client.SimpleMethodClient
The custom-client.xml file (Listing 6) binds the package to the WSDL:
<bindings wsdlLocation="http://localhost:8080/jaxws-simpleexample/simplemethod?wsdl"> <bindings node="wsdl:definitions"> <package name="simpleexample.client"/> </bindings> </bindings>
The custom-schema.xml file (Listing 7) binds the package to the schema:
<bindings schemaLocation="http://localhost:8080/jaxws-simpleexample/simplemethod?xsd=1 " node="/xsd:schema"> <schemaBindings> <package name="simpleexample.client"/> </schemaBindings> </bindings>
Of course, much of this code can be generated by a development tool very simply. As the next section demonstrates, coding all these cookie cutter files by hand can be tedious. As with most JSRs, JAX-WS was designed by Java tool vendors for Java tool vendors. What JAX-WS really does is provide the framework by which the developer's tool of choice can provide one-click generation of a Web service and client skeleton.
<!---->
|
By following these steps you have transformed your own Java class into a Web service, enabling it to communicate over a network in a distributed computing environment.