Lesson 2: Creating a Java Application to Communicate with the Web Server

In this lesson, you process the WSDL document generated from the DISH service and create a Java application to access table data based on the schema defined in the WSDL document.

Prerequisites

This lesson depends on the steps carried out in lesson 1.

This lesson assumes that you have the roles and privileges listed in the Privileges section at the start of this tutorial: Tutorial: Using JAX-WS to access a SOAP/DISH web service.

Task

At the time of writing, JAX-WS is included in JDK 1.7.0 and the most recent version of JAX-WS was 2.2.7. The steps that follow are based on that version. To determine if JAX-WS is present in your JDK, check for the wsimport application in the JDK bin directory. If it is not there then go to http://jax-ws.java.net/ to download and install the latest version of JAX-WS.

This lesson contains several references to localhost. Use the host name or IP address of the web server from lesson 1 instead of localhost if you are not running the web client on the same computer as the web server.

  1. At a command prompt, create a new working directory for your Java code and generated files. Change to this new directory.
  2. Generate the interface that calls the DISH web service and imports the WSDL document using the following command:
    wsimport -keep "http://localhost:8082/demo/WSDish"

    The wsimport application retrieves the WSDL document from the given URL. It generates .java files to create an interface for it, then compiles them into .class files.

    The keep option indicates that the .java files should not be deleted after generating the class files. The generated Java source code allows you to understand the generated class files.

    The wsimport application creates a new subdirectory structure named localhost\_8082\demo\ws in your current working directory. The following is a list of the contents of directory ws:

    • EmployeeList.class

    • EmployeeList.java

    • EmployeeListDataset$Rowset$Row.class

    • EmployeeListDataset$Rowset.class

    • EmployeeListDataset.class

    • EmployeeListDataset.java

    • EmployeeListResponse.class

    • EmployeeListResponse.java

    • FaultMessage.class

    • FaultMessage.java

    • ObjectFactory.class

    • ObjectFactory.java

    • package-info.class

    • package-info.java

    • WSDish.class

    • WSDish.java

    • WSDishSoapPort.class

    • WSDishSoapPort.java

  3. Write a Java application that accesses table data from the database server based on the dataset object schema defined in the generated source code.

    The following is a sample Java application that does this. Save the source code as SASoapDemo.java in the current working directory. Your current working directory must be the directory containing the localhost subdirectory.

    // SASoapDemo.java illustrates a web service client that
    // calls the WSDish service and prints out the data.
    
    import java.util.*;
    import javax.xml.ws.*;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import javax.xml.datatype.*;
    import localhost._8082.demo.ws.*;
    
    public class SASoapDemo
    {
      public static void main( String[] args )
      {
        try {
          WSDish service = new WSDish();
    
          Holder<EmployeeListDataset> response = 
              new Holder<EmployeeListDataset>();
          Holder<Integer> sqlcode = new Holder<Integer>();
                
          WSDishSoapPort port = service.getWSDishSoap();
    
          // This is the SOAP service call to EmployeeList
          port.employeeList( response, sqlcode );
    
          EmployeeListDataset result = response.value;
          EmployeeListDataset.Rowset rowset = result.getRowset();
    
          List<EmployeeListDataset.Rowset.Row> rows = rowset.getRow();
    
          String fieldType;
          String fieldName;
          String fieldValue;
          Integer fieldInt;
          XMLGregorianCalendar fieldDate;
          
          for ( int i = 0; i < rows.size(); i++ ) {
            EmployeeListDataset.Rowset.Row row = rows.get( i );
    
            fieldType = row.getEmployeeID().getDeclaredType().getSimpleName();
            fieldName = row.getEmployeeID().getName().getLocalPart();
            fieldInt = row.getEmployeeID().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldInt );
            
            fieldType = row.getSurname().getDeclaredType().getSimpleName();
            fieldName = row.getSurname().getName().getLocalPart();
            fieldValue = row.getSurname().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldValue );
            
            fieldType = row.getGivenName().getDeclaredType().getSimpleName();
            fieldName = row.getGivenName().getName().getLocalPart();
            fieldValue = row.getGivenName().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                 "=" + fieldValue );
            
            fieldType = row.getStartDate().getDeclaredType().getSimpleName();
            fieldName = row.getStartDate().getName().getLocalPart();
            fieldDate = row.getStartDate().getValue();
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldDate );
            
            if ( row.getTerminationDate() == null ) {
              fieldType = "unknown";
              fieldName = "TerminationDate";
              fieldDate = null;
            } else {
              fieldType = 
                row.getTerminationDate().getDeclaredType().getSimpleName();
              fieldName = row.getTerminationDate().getName().getLocalPart();
              fieldDate = row.getTerminationDate().getValue();
            }
            System.out.println( "(" + fieldType + ")" + fieldName + 
                                "=" + fieldDate );
            System.out.println();
          }
        }
        catch (Exception x) {
          x.printStackTrace();
        }
      }
    }

    This application prints all server-provided column data to the standard system output.

    Note: This application assumes that your SAP Sybase IQ web server is listening on port 8082, as instructed in lesson one. Replace the 8082 portion of the import localhost._8082.demo.ws.* code line with the port number you specified when you started the SAP Sybase IQ web server.

    For more information about the Java methods used in this application, see the javax.xml.bind.JAXBElement class API documentation at http://docs.oracle.com/javase/.

  4. Compile your Java application using the following command:
    javac SASoapDemo.java
  5. Execute the application using the following command:
    java SASoapDemo
  6. The application sends its request to the web server. It receives an XML result set response that consists of an EmployeeListResult with a rowset containing several row entries.

The following is an example of the output from running SASoapDemo:

(Integer)EmployeeID=102
(String)Surname=Whitney
(String)GivenName=Fran
(XMLGregorianCalendar)StartDate=1984-08-28
(unknown)TerminationDate=null

(Integer)EmployeeID=105
(String)Surname=Cobb
(String)GivenName=Matthew
(XMLGregorianCalendar)StartDate=1985-01-01
(unknown)TerminationDate=null
.
.
.
(Integer)EmployeeID=1740
(String)Surname=Nielsen
(String)GivenName=Robert
(XMLGregorianCalendar)StartDate=1994-06-24
(unknown)TerminationDate=null

(Integer)EmployeeID=1751
(String)Surname=Ahmed
(String)GivenName=Alex
(XMLGregorianCalendar)StartDate=1994-07-12
(XMLGregorianCalendar)TerminationDate=2008-04-18

The TerminationDate column is only sent when its value is not NULL. The Java application is designed to detect when the TerminationDate column is not present. For this example, the last row in the Employees table was altered such that a non-NULL termination date was set.

The following is an example of a SOAP response from the web server. The SQLCODE result from executing the query is included in the response.

<tns:EmployeeListResponse>
 <tns:EmployeeListResult xsi:type='tns:EmployeeListDataset'>
  <tns:rowset>
    <tns:row> ... </tns:row>
    .
    .
    .
    <tns:row>
      <tns:EmployeeID xsi:type="xsd:int">1751</tns:EmployeeID>
      <tns:Surname xsi:type="xsd:string">Ahmed</tns:Surname>
      <tns:GivenName xsi:type="xsd:string">Alex</tns:GivenName>
      <tns:StartDate xsi:type="xsd:dateTime">1994-07-12</tns:StartDate>
      <tns:TerminationDate xsi:type="xsd:dateTime">2010-03-22</tns:TerminationDate>
    </tns:row>
  </tns:rowset>
 </tns:EmployeeListResult>
 <tns:sqlcode>0</tns:sqlcode>
</tns:EmployeeListResponse>

Column names and data types are included in each rowset.