Standards for Technology in Automotive Retail

 
 Home -  News Feed 

Chapter 6. Java Examples

Table of Contents

6.1. JAX-WS 2.x
6.1.1. Prerequisites
6.1.2. JAX-WS Walkthrough
6.2. Apache Axis 2
6.2.1. Prerequisites
6.2.2. Apache Axis 2 Walkthrough

6.1. JAX-WS 2.x

This example uses Sun’s JAX-WS implementation to create a Web Service and client. The JAX-WS implementation is part of the Metro Web Service framework, a subset of Sun’s Project GlassFish and a continuation of the work Sun packaged as the Java Web Services Developer Pack (JWSDP). The homepage for Metro is https://metro.dev.java.net/ . The target runtime for the service is the Apache Tomcat Server. The client will be a standalone application.

This example was created using the JDK 5.0 Update 14, JAX-WS 2.1.2, and Tomcat 5.5. While some of the screen shots will show Eclipse 3.3, Eclipse is not required for this example. Eclipse was primarily used to give a visual representation of the WAR, but it was used in some instances for source editing.

6.1.1. Prerequisites

  1. JAX-WS can be downloaded from the JAX-WS homepage at https://jax-ws.dev.java.net/

  2. Since our target runtime is Tomcat, refer to the Tomcat homepage ( http://tomcat.apache.org/ ) for download and installation instructions.

  3. Both service and client will be generated using the wsimport tool included with JAX-WS. This tool can be found in <JAX-WS Install Directory>\jaxws-ri\bin\wsimport.bat. A document describing the tool is available at <JAX-WS Install Directory>\jaxws-ri\docs\wsimport.html.

6.1.2. JAX-WS Walkthrough

Procedure 6.1. Add Address Information to the WSDL

  1. If the WSDL was retrieved from STAR repository, the service information in the WSDL is incomplete. It must be changed to reflect your Web Service implementation. An unmodified WSDL will have an XML comment beginning with “Note to implementors…” along with an example of what the address information should look like. The example below is based off of the ProcessRetailDeliveryReporting.wsdl in Rev5.2.1. Assuming you are running a local instance of Tomcat, with 8080 as your HTTP port, the service information will look like the following:

    Example 6.1. Sample Service

    <wsdl:service name="ProcessRetailDeliveryReportingWebService">
       <wsdl:port name="ProcessRetailDeliveryReportingStarTransport" binding="starbindings:starTransport">
          <soap:address location="http://localhost:8080/StarQuickStartService/StarTransport/"/>
       </wsdl:port>
    </wsdl:service>
            

    Once the WSDL has been edited with the address information, it can be used by wsimport to produce source for the service and client, as well as classes for JAXB marshalling and unmarshalling.

  2. At a windows command prompt, move to the <JAX-WS Install Directory>\jaxws-ri\bin directory. Execute the wsimport script. Be sure to set the output location for the source (-s) since the default behavior is to produce compiled code. This location must already exist since the script will not create the directory for you. It will give an error, “directory not found…” if the directory does not exist. Also, if you run into memory errors, edit the wsimport.bat script to increase the Java heap size. For this example the initial and maximum values were increased to 512MB, so the launch section of the wsimport.bat script looked like this (edited section in bold):

    %JAVA% %WSIMPORT_OPTS% -Xms512M -Xmx512M -jar "%JAXWS_HOME%\lib\jaxws-tools.jar" %*
        

    Example 6.2. Example WSImport command

    wsimport -d classes -s src -verbose C:\JAX-WS\jaxws-ri\bin\STAR\Rev5.1.2\WSDL\ProcessRetailDeliveryReporting.wsdl > results.txt   
            

  3. Import the generated source into a WAR, adding the necessary jar files from <JAX-WS Install Directory>\jaxws-ri\lib

    Figure 6.1. Import Source

    Import Source

  4. Create the Web Service implementation class. This class can implement the StarTransportPortTypes interface that was created by wsimport. It is not required that it implement the interface, though it may help if using an IDE since the IDE can generate the inherited abstract methods. For this example, I called my class ProcessRetailDeliveryReportingWebServiceImpl. Once this class is created, add an annotation above the class declaration to refer to the endpointInterface:

    @javax.jws.WebService (endpointInterface="org.starstandards.webservices._2005._10.transport.bindings.StarTransportPortTypes")  
        
  5. For now, only add print statements to the implementation class so you can tell when you have called the method via the client that we will soon create. Below is how your ProcessRetailDeliverWebServiceImpl class should currently look:

    package org.starstandards.webservices._2005._10.transport.bindings;
    
    import org.starstandards.webservices._2005._10.transport.AcknowledgeRetailDeliveryReportingPayload;
    import org.starstandards.webservices._2005._10.transport.ProcessRetailDeliveryReportingPayload;
    
    @javax.jws.WebService (endpointInterface="org.starstandards.webservices._2005._10.transport.bindings.StarTransportPortTypes")
    public class ProcessRetailDeliveryReportingWebServiceImpl implements
                    StarTransportPortTypes {
    
            public AcknowledgeRetailDeliveryReportingPayload processMessage(
                            ProcessRetailDeliveryReportingPayload payload) {
                    System.out.println("Called processMessage");
                    return null;
            }
    
            @SuppressWarnings("unchecked")
            public AcknowledgeRetailDeliveryReportingPayload pullMessage()
            {
                System.out.println("Called pullMessage!");
                return null;
            }
    
            public void putMessage(ProcessRetailDeliveryReportingPayload payload) {
                    System.out.println("Called putMessage");
            }
    }
        

Before our service is complete, we need to configure the application so that a Web Service call will be routed to the implementation class we just created. This is done by editing the web.xml and creating a JAX-WS configuration file, sun-jaxws.xml.

Three items need to be added to the web.xml:

  1. A listener reference to the JAX-WS WSServletContextListener

  2. A servlet reference to the JAX-WS WSServlet servlet

  3. A servlet-mapping reference for the above servlet

For this example, here are those following items:

<listener>
   <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
   <servlet-name>StarTransportPort</servlet-name>
   <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
   <servlet-name>StarTransportPort</servlet-name>
   <url-pattern>/StarTransport</url-pattern>
</servlet-mapping>

Procedure 6.2. Create the sun-jaxws.xml

  1. Now it’s time to create the sun-jaxws.xml. This file resides in the same location as the web.xml, the WEB-INF folder. Below is the content of the file for this example:

    Example 6.3. sun-jaxws.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
       <endpoint 
             name="starTransportPortTypes" 
             interface="org.starstandards.webservices._2005._10.transport.bindings.StarTransportPortTypes"
             implementation="org.starstandards.webservices._2005._10.transport.bindings.ProcessRetailDeliveryReportingWebServiceImpl"
             url-pattern="/StarTransport"
      />
    </endpoints>
            

    [Note]Note

    Note that the endpoint name is the same as the name that you see on the Java annotation from the StarTransportPortTypes class. Also, the interface and implementation classes are provided. The url-pattern provided must match what is in the web.xml file.

  2. The service is now ready to deploy. Deploy the WAR to Tomcat or the application server you are working with. You can confirm installation by accessing the service’s URL. For this example, the service can be accessed at http://localhost:8080/StarQuickStartServiceJAXWS/StarTransport in a browser. The following should be returned:

    Figure 6.2. JAX-WS Deploy Endpoint

    JAX-WS Deploy Endpoint

Procedure 6.3. Create JAX-WS Client

  1. Now it is time to create the client. Since the client uses the same source files generated by wsimport that were used for the service, the only item to create is a new class and method that will use the generated code to call the service. Below is an example of a test client that calls the PullMessage method. Since there is currently no implementation code in our service, we will at least see the print statement (“Called pullMessage”) from the service printed to the standard output of the application server. Until implementation code is added to the service to return a valid response, this client will throw an exception.

    package org.star.quickstart.client;
    
    import org.openapplications.oagis._9.unqualifieddatatypes._1.IdentifierType;
    import org.starstandard.star._5.AcknowledgeRetailDeliveryReportingType;
    import org.starstandard.star._5.ApplicationAreaType;
    import org.starstandards.webservices._2005._10.transport.AcknowledgeRetailDeliveryReportingContent;
    import org.starstandards.webservices._2005._10.transport.AcknowledgeRetailDeliveryReportingPayload;
    import org.starstandards.webservices._2005._10.transport.bindings.ProcessRetailDeliveryReportingWebService;
    import org.starstandards.webservices._2005._10.transport.bindings.StarTransportPortTypes;
    
    public class TestClient {
        public static void main(String[] args)
        {
           ProcessRetailDeliveryReportingWebService stub = new ProcessRetailDeliveryReportingWebService();
           StarTransportPortTypes port = stub.getProcessRetailDeliveryReportingStarTransport();
               ((javax.xml.ws.BindingProvider)port).getRequestContext()
                      .put(javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                           "http://localhost:8080/StarQuickStartServiceJAXWS/StarTransport");
           AcknowledgeRetailDeliveryReportingPayload payload = port.pullMessage();
           AcknowledgeRetailDeliveryReportingContent content = payload.getContent().get(0);
           AcknowledgeRetailDeliveryReportingType bod = content.getAcknowledgeRetailDeliveryReporting();
           ApplicationAreaType applicationArea = bod.getApplicationArea();
           IdentifierType BODID = applicationArea.getBODID();
           System.out.println("BODID returned: " + BODID.getValue());
        }
    }
          
  2. Once you have created the TestClient class, execute the main method and verify that “pullMessage” has been written to the application server logs by the service.

  3. Now that we have verified that the client can communicate to the service, we can add some JAXB unmarshalling code to service to simulate producing a valid response. Similarly, we can add marshalling code to the client to print out the AcknowledgeRetailDeliveryReporting BOD returned from the service.

    Below is the code added to the pullMessage method of the service implementation class. In this example, the BOD is being read straight from the “examples” directory of a STAR repository. Using the JAXB unmarshaller, the xml data from the file is placed into the Java objects reference by the AcknowledgeRetailDeliveryReportingType class.

    @SuppressWarnings("unchecked")
        public AcknowledgeRetailDeliveryReportingPayload pullMessage()
        {
             System.out.println("Called pullMessage!");
             AcknowledgeRetailDeliveryReportingPayload response = new AcknowledgeRetailDeliveryReportingPayload();
             AcknowledgeRetailDeliveryReportingContent content = new AcknowledgeRetailDeliveryReportingContent();
    
             try
             {
                JAXBContext jaxbContext = JAXBContext.newInstance("org.starstandard.star._5");
                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
                JAXBElement<AcknowledgeRetailDeliveryReportingType> bod = 
                    (JAXBElement<AcknowledgeRetailDeliveryReportingType>) unmarshaller
         				.unmarshal(new File("C:\\jaxws-ri\\bin\\STAR\\Rev5.2.1\\BODExamples\\AcknowledgeRetailDeliveryReporting.xml"));
    
                content.setAcknowledgeRetailDeliveryReporting(bod.getValue());
             }
               catch(Exception e)
               {
                  e.printStackTrace();
               }
    
            response.getContent().add(content);
    
            return response;
    }
          
  4. Before adding the marshalling code to the client, deploy the service again with the updated implementation code from above. Invoke the service with the TestClient created earlier. If successful, the BOD Id will be printed.

    Below is the code added to the TestClient to take the results from the PullMessage call and print the resulting XML to the standard output stream. The JAXB marshaller is used to get the XML content from the Java object.

    package org.star.quickstart.client;
    
    import java.io.StringWriter;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBElement;
    import javax.xml.bind.Marshaller;
    
    import org.starstandard.star._5.AcknowledgeRetailDeliveryReportingType;
    import org.starstandards.webservices._2005._10.transport.AcknowledgeRetailDeliveryReportingContent;
    import org.starstandards.webservices._2005._10.transport.AcknowledgeRetailDeliveryReportingPayload;
    import org.starstandards.webservices._2005._10.transport.bindings.ProcessRetailDeliveryReportingWebService;
    import org.starstandards.webservices._2005._10.transport.bindings.StarTransportPortTypes;
    
    public class TestClient {
    
        public static void main(String[] args) 
        {
           ProcessRetailDeliveryReportingWebService stub = new ProcessRetailDeliveryReportingWebService();
           StarTransportPortTypes port = stub.getProcessRetailDeliveryReportingStarTransport();
               ((javax.xml.ws.BindingProvider)port).getRequestContext()
     				.put(javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
     					 "http://localhost:8080/StarQuickStartServiceJAXWS/StarTransport");
           AcknowledgeRetailDeliveryReportingPayload payload = port.pullMessage();
           AcknowledgeRetailDeliveryReportingContent content = payload.getContent().get(0);
           AcknowledgeRetailDeliveryReportingType bod = content.getAcknowledgeRetailDeliveryReporting();
    
           try
           {
              JAXBContext jaxbContext = JAXBContext.newInstance("org.starstandard.star._5");
              Marshaller marshaller = jaxbContext.createMarshaller();
    
              JAXBElement<AcknowledgeRetailDeliveryReportingType> processRetailDeliveryReportingElement =
                    (new org.starstandard.star._5.ObjectFactory()).createAcknowledgeRetailDeliveryReporting(bod);
              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
              StringWriter writer = new StringWriter();
              marshaller.marshal( processRetailDeliveryReportingElement, writer );
              String xmlStr = writer.toString();
    
              System.out.println(xmlStr);
           }
           catch(Exception e)
           {
              e.printStackTrace();
           }
    
        }
    }
          
  5. After adding this code to the TestClient class, run the main method again. Now the entire AcknowledgeRetailDeliveryReporting BOD will be printed.