9 Examples of Developing JAX-WS Web Service Clients

This chapter provides some common examples of developing WebLogic web service clients using Java API for XML-based Web services (JAX-WS).

This chapter includes the following sections:

Each example provides step-by-step procedures for creating simple WebLogic web services and invoking an operation from a deployed web service. The examples include basic Java code and Ant build.xml files that you can use in your own development environment to recreate the example, or by following the instructions to create and run the examples in an environment that is separate from your development environment.

The examples do not go into detail about the processes and tools used in the examples; later chapters are referenced for more detail.

Note:

For best practice examples demonstrating advanced web service features, see Roadmap for Developing JAX-WS Web Service Clients and Roadmap for Developing Reliable Web Services and Clients.

Developing a JAX-WS Java SE Client

Note:

You can invoke a web service from any Java SE or Java EE application running on WebLogic Server (with access to the WebLogic Server classpath). Invoking a web service from standalone Java applications that are running in an environment where WebLogic Server libraries are not available is not supported in this release for JAX-WS web services.

When you invoke an operation of a deployed web service from a client application, the web service could be deployed to WebLogic Server or to any other application server, such as .NET. All you need to know is the URL to its public contract file, or WSDL.

In addition to writing the Java client application, you must also run the clientgen WebLogic web service Ant task to generate the artifacts that your client application needs to invoke the web service operation. These artifacts include:

  • The Java class for the Service interface implementation for the particular web service you want to invoke.

  • JAXB data binding artifacts.

  • The Java class for any user-defined XML Schema data types included in the WSDL file.

The following example shows how to create a Java client application that invokes the echoComplexType operation of the ComplexService WebLogic web service described in Creating a Web Service With User-Defined Data Types. The echoComplexType operation takes as both a parameter and return type the BasicStruct user-defined data type.

Note:

It is assumed in this procedure that you have created and deployed the ComplexService web service.

  1. Set your WebLogic Server environment.

    Open a command window and execute the setDomainEnv.cmd (Windows) or setDomainEnv.sh (UNIX) script, located in the bin subdirectory of your domain directory. The default location of WebLogic Server domains is ORACLE_HOME/user_projects/domains/domainName, where ORACLE_HOME is the directory you specified as Oracle Home when you installed Oracle WebLogic Server and domainName is the name of your domain.

  2. Create a project directory:
       prompt> mkdir /myExamples/simple_client
    
  3. Create a src directory under the project directory, as well as subdirectories that correspond to the package name of the Java client application (shown later on in this procedure):
       prompt> cd /myExamples/simple_client
       prompt> mkdir src/examples/webservices/simple_client
    
  4. Create a standard Ant build.xml file in the project directory and add a taskdef Ant task to specify the full Java classname of the clientgen task:
    <project name="webservices-simple_client" default="all">
      <taskdef name="clientgen"
        classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
    </project>
    

    See Sample Ant Build File For Building Java Client Application for a full sample build.xml file. The full build.xml file uses properties, such as ${clientclass-dir}, rather than always using the hard-coded name output directory for client classes.

  5. Add the following calls to the clientgen and javac Ant tasks to the build.xml file, wrapped inside of the build-client target:
      <target name="build-client">
        <clientgen
          wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
          destDir="output/clientclass"
          packageName="examples.webservices.simple_client"
          type="JAXWS"/>
        <javac
          srcdir="output/clientclass" destdir="output/clientclass"
          includes="**/*.java"/>
     <javac
        srcdir="src" destdir="output/clientclass"
        includes="examples/webservices/simple_client/*.java"/>
    </target>
    

    The clientgen Ant task uses the WSDL of the deployed ComplexService web service to generate the necessary artifacts and puts them into the output/clientclass directory, using the specified package name. Replace the variables with the actual hostname and port of your WebLogic Server instance that is hosting the web service.

    In this example, the package name is set to the same package name as the client application, examples.webservices.simple_client. If you set the package name to one that is different from the client application, you would need to import the appropriate class files. For example, if you defined the package name as examples.webservices.complex, you would need to import the following class files in the client application:

    import examples.webservices.complex.BasicStruct;
    import examples.webservices.complex.ComplexPortType;
    import examples.webservices.complex.ComplexService;
    

    The clientgen Ant task also automatically generates the examples.webservices.simple_client.BasicStruct JavaBean class, which is the Java representation of the user-defined data type specified in the WSDL.

    The build-client target also specifies the standard javac Ant task, in addition to clientgen, to compile all the Java code, including the Java program described in the next step, into class files.

    The clientgen Ant task also provides the destFile attribute if you want the Ant task to automatically compile the generated Java code and package all artifacts into a JAR file. For details and an example, see "clientgen" in the WebLogic Web Services Reference for Oracle WebLogic Server.

  6. Create the Java client application file that invokes the echoComplexType operation.

    Open your favorite Java IDE or text editor and create a Java file called Main.java using the code specified in Sample Java Client Application.

    The application follows standard JAX-WS guidelines to invoke an operation of the web service using the web service-specific implementation of the Service interface generated by clientgen. For details, see Developing Web Service Clients.

  7. Save the Main.java file in the src/examples/webservices/simple_client subdirectory of the main project directory.
  8. Execute the clientgen and javac Ant tasks by specifying the build-client target at the command line:
    prompt> ant build-client
    

    See the output/clientclass directory to view the files and artifacts generated by the clientgen Ant task.

  9. Add the following targets to the build.xml file, used to execute the Main application:
      <path id="client.class.path">
        <pathelement path="output/clientclass"/>
        <pathelement path="${java.class.path}"/>
      </path>
      <target name="run" >
        <java fork="true"
              classname="examples.webservices.simple_client.Main"
              failonerror="true" >
          <classpath refid="client.class.path"/>
      </target>
    

    The run target invokes the Main application, passing it the WSDL URL of the deployed web service as its single argument. The classpath element adds the clientclass directory to the CLASSPATH, using the reference created with the <path> task.

  10. Execute the run target to invoke the echoComplexType operation:
        prompt> ant run
    

    If the invoke was successful, you should see the following final output:

    run:
         [java] echoComplexType called. Result: 999, Hello Struct
    

You can use the build-client and run targets in the build.xml file to iteratively update, rebuild, and run the Java client application as part of your development process.

Sample Java Client Application

The following provides a simple Java client application that invokes the echoComplexType operation. Because the <clientgen> packageName attribute was set to the same package name as the client application, we are not required to import the <clientgen>-generated files.

package examples.webservices.simple_client;
/**
 * This is a simple Java application that invokes the
 * echoComplexType operation of the ComplexService web service.
 */
public class Main {
  public static void main(String[] args) { 
    ComplexService test = new ComplexService();
    ComplexPortType port = test.getComplexPortTypePort();
    BasicStruct in = new BasicStruct();
    in.setIntValue(999);
    in.setStringValue("Hello Struct");
    BasicStruct result = port.echoComplexType(in);
    System.out.println("echoComplexType called. Result: " + result.getIntValue() + ", " + result.getStringValue());
  }
}

Sample Ant Build File For Building Java Client Application

The following build.xml file defines tasks to build the Java client application. The example uses properties to simplify the file.

<project name="webservices-simple_client" default="all">
  <!-- set global properties for this build -->
  <property name="wls.hostname" value="localhost" />
  <property name="wls.port" value="7001" />
  <property name="example-output" value="output" />
  <property name="clientclass-dir" value="${example-output}/clientclass" />
  <path id="client.class.path">
    <pathelement path="${clientclass-dir}"/>
    <pathelement path="${java.class.path}"/>
  </path>
  <taskdef name="clientgen"
    classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
  <target name="clean" >
    <delete dir="${clientclass-dir}"/>
  </target>
  <target name="all" depends="clean,build-client,run" />
  <target name="build-client">
    <clientgen
     type="JAXWS"
     wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
      destDir="${clientclass-dir}"
      packageName="examples.webservices.simple_client"/>
    <javac
      srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
      includes="**/*.java"/>
    <javac
      srcdir="src" destdir="${clientclass-dir}"
      includes="examples/webservices/simple_client/*.java"/>
  </target>
  <target name="run" >
    <java fork="true"
          classname="examples.webservices.simple_client.Main"
          failonerror="true" >
      <classpath refid="client.class.path"/>
    </java>
  </target>
</project>

Invoking a Web Service from a WebLogic Web Service

You can invoke a web service (WebLogic, Microsoft .NET, and so on) from within a deployed WebLogic web service.

The procedure is similar to that described in Developing a JAX-WS Java SE Client except that instead of running the clientgen Ant task to generate the client stubs, you use the <clientgen> child element of <jws>, inside of the jwsc Ant task. The jwsc Ant task automatically packages the generated client stubs in the invoking web service WAR file so that the web service has immediate access to them. You then follow standard JAX-WS programming guidelines in the JWS file that implements the web service that invokes the other web service.

The following example shows how to write a JWS file that invokes the echoComplexType operation of the ComplexService web service described in Creating a Web Service With User-Defined Data Types.

Note:

It is assumed that you have successfully deployed the ComplexService web service.

  1. Set your WebLogic Server environment.

    Open a command window and execute the setDomainEnv.cmd (Windows) or setDomainEnv.sh (UNIX) script, located in the bin subdirectory of your domain directory. The default location of WebLogic Server domains is ORACLE_HOME/user_projects/domains/domainName, where ORACLE_HOME is the directory you specified as Oracle Home when you installed Oracle WebLogic Server and domainName is the name of your domain.

  2. Create a project directory:
       prompt> mkdir /myExamples/service_to_service
    
  3. Create a src directory under the project directory, as well as subdirectories that correspond to the package name of the JWS and client application files (shown later on in this procedure):
       prompt> cd /myExamples/service_to_service
       prompt> mkdir src/examples/webservices/service_to_service
    
  4. Create the JWS file that implements the web service that invokes the ComplexService web service.

    Open your favorite Java IDE or text editor and create a Java file called ClientServiceImpl.java using the Java code specified in Sample ClientServiceImpl.java JWS File.

    The sample JWS file shows a Java class called ClientServiceImpl that contains a single public method, callComplexService(). The Java class imports the JAX-WS stubs, generated later on by the jwsc Ant task, as well as the BasicStruct JavaBean (also generated by clientgen), which is the data type of the parameter and return value of the echoComplexType operation of the ComplexService web service.

    The ClientServiceImpl Java class defines one method, callComplexService(), which takes one parameter: a BasicStruct which is passed on to the echoComplexType operation of the ComplexService web service. The method then uses the standard JAX-WS APIs to get the Service and PortType of the ComplexService, using the stubs generated by jwsc, and then invokes the echoComplexType operation.

  5. Save the ClientServiceImpl.java file in the src/examples/webservices/service_to_service directory.
  6. Create a standard Ant build.xml file in the project directory and add the following task:
    <project name="webservices-service_to_service" default="all">
      <taskdef name="jwsc"
        classname="weblogic.wsee.tools.anttasks.JwscTask" />
    </project>
    

    The taskdef task defines the full classname of the jwsc Ant task.

    See Sample Ant Build File For Building ClientService for a full sample build.xml file that contains additional targets from those described in this procedure, such as clean, deploy, undeploy, client, and run. The full build.xml file also uses properties, such as ${ear-dir}, rather than always using the hard-coded name for the EAR directory.

  7. Add the following call to the jwsc Ant task to the build.xml file, wrapped inside of the build-service target:
    <target name="build-service">
      <jwsc
        srcdir="src"
        destdir="output/ClientServiceEar" >
        <jws
          file="examples/webservices/service_to_service/ClientServiceImpl.java"
         type="JAXWS">
                <WLHttpTransport
                 contextPath="ClientService" serviceUri="ClientService"
                 portName="ClientServicePort"/>
         <clientgen
           type="JAXWS"
    wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
           packageName="examples.webservices.complex" />
        </jws>
      </jwsc>
    </target>
    

    In the preceding example, the <clientgen> child element of the <jws> element of the jwsc Ant task specifies that, in addition to compiling the JWS file, jwsc should also generate and compile the client artifacts needed to invoke the web service described by the WSDL file.

    In this example, the package name is set to examples.webservices.complex, which is different from the client application package name, examples.webservices.simple_client. As a result, you need to import the appropriate class files in the client application:

    import examples.webservices.complex.BasicStruct;
    import examples.webservices.complex.ComplexPortType;
    import examples.webservices.complex.ComplexService;
    

    If the package name is set to the same package name as the client application, the import calls would be optional.

  8. Execute the jwsc Ant task by specifying the build-service target at the command line:
    prompt> ant build-service
    
  9. Start the WebLogic Server instance to which you will deploy the web service.
  10. Deploy the web service, packaged in an Enterprise Application, to WebLogic Server, using either the WebLogic Server Administration Console or the wldeploy Ant task. In either case, you deploy the ClientServiceEar Enterprise application, located in the output directory.

    To use the wldeploy Ant task, add the following target to the build.xml file:

      <taskdef name="wldeploy"
               classname="weblogic.ant.taskdefs.management.WLDeploy"/>
      <target name="deploy">
        <wldeploy action="deploy" name="ClientServiceEar"
          source="ClientServiceEar" user="${wls.username}"
          password="${wls.password}" verbose="true"
          adminurl="t3://${wls.hostname}:${wls.port}"
          targets="${wls.server.name}" />
      </target>
    

    Substitute the values for wls.username, wls.password, wls.hostname, wls.port, and wls.server.name that correspond to your WebLogic Server instance.

    Deploy the WAR file by executing the deploy target:

      prompt> ant deploy
    
  11. Test that the web service is deployed correctly by invoking its WSDL in your browser:
    http://host:port/ClientService/ClientService?WSDL
    

See Developing a JAX-WS Java SE Client for an example of creating a Java client application that invokes a web service.

Sample ClientServiceImpl.java JWS File

The following provides a simple web service client application that invokes the echoComplexType operation.

package examples.webservices.service_to_service;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.ws.WebServiceRef;

// Import the BasicStruct data type, generated by clientgen and used
// by the ComplexService Web Service
import examples.webservices.complex.BasicStruct;

// Import the JAX-WS stubs generated by clientgen for invoking
// the ComplexService web service.
import examples.webservices.complex.ComplexPortType;
import examples.webservices.complex.ComplexService;

@WebService(name="ClientPortType", serviceName="ClientService",
            targetNamespace="http://examples.org")
public class ClientServiceImpl {
// Use the @WebServiceRef annotation to define a reference to the 
// ComplexService web service.
  @WebServiceRef()
  ComplexService test;

  @WebMethod()
  public String callComplexService(BasicStruct input, String serviceUrl) 
  {
    // Create a port stub to invoke ComplexService
    ComplexPortType port = test.getComplexPortTypePort();

    // Invoke the echoComplexType operation of ComplexService
    BasicStruct result = port.echoComplexType(input);
    System.out.println("Invoked ComplexPortType.echoComplexType." );
    return "Invoke went okay!  Here's the result: '" + result.getIntValue() + 
           ",  " + result.getStringValue() + "'";
  }
}

Sample Ant Build File For Building ClientService

The following build.xml file defines tasks to build the client application. The example uses properties to simplify the file.

The following build.xml file uses properties to simplify the file.

<project name="webservices-service_to_service" default="all">
  <!-- set global properties for this build -->
  <property name="wls.username" value="weblogic" />
  <property name="wls.password" value="weblogic" />
  <property name="wls.hostname" value="localhost" />
  <property name="wls.port" value="7001" />
  <property name="wls.server.name" value="myserver" />
  <property name="ear.deployed.name" value="ClientServiceEar" />
  <property name="example-output" value="output" />
  <property name="ear-dir" value="${example-output}/ClientServiceEar" />
  <property name="clientclass-dir" value="${example-output}/clientclasses" />
  <path id="client.class.path">
    <pathelement path="${clientclass-dir}"/>
    <pathelement path="${java.class.path}"/>
  </path>
  <taskdef name="jwsc"
    classname="weblogic.wsee.tools.anttasks.JwscTask" />
  <taskdef name="clientgen"
    classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
  <taskdef name="wldeploy"
    classname="weblogic.ant.taskdefs.management.WLDeploy"/>
  <target name="all" depends="clean,build-service,deploy,client" />
  <target name="clean" depends="undeploy">
    <delete dir="${example-output}"/>
  </target>
  <target name="build-service">
    <jwsc
        srcdir="src"
        destdir="${ear-dir}" >
       <jws
         file="examples/webservices/service_to_service/ClientServiceImpl.java"
         type="JAXWS">
         <WLHttpTransport
          contextPath="ClientService" serviceUri="ClientService"
          portName="ClientServicePort"/>
         <clientgen
               type="JAXWS"
           wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
                packageName="examples.webservices.complex" />
       </jws>
    </jwsc>
  </target>
  <target name="deploy">
    <wldeploy action="deploy" name="${ear.deployed.name}"
      source="${ear-dir}" user="${wls.username}"
      password="${wls.password}" verbose="true"
      adminurl="t3://${wls.hostname}:${wls.port}"
      targets="${wls.server.name}" />
  </target>
  <target name="undeploy">
    <wldeploy action="undeploy" name="${ear.deployed.name}"
      failonerror="false"
      user="${wls.username}"
      password="${wls.password}" verbose="true"
      adminurl="t3://${wls.hostname}:${wls.port}"
      targets="${wls.server.name}" />
  </target>
  <target name="client">
    <clientgen
      wsdl="http://${wls.hostname}:${wls.port}/ClientService/ClientService?WSDL"
      destDir="${clientclass-dir}"
      packageName="examples.webservices.service_to_service.client"
      type="JAXWS"/>
    <javac
      srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
      includes="**/*.java"/>
    <javac
      srcdir="src" destdir="${clientclass-dir}"
      includes="examples/webservices/service_to_service/client/**/*.java"/>
  </target>
  <target name="run">
    <java classname="examples.webservices.service_to_service.client.Main"
          fork="true"
          failonerror="true" >
          <classpath refid="client.class.path"/>
    </java>
  </target>
</project>