6 Invoking Web Services

This chapter describes how to invoke WebLogic Web services using Java API for XML-based RPC (JAX-RPC).

This chapter includes the following topics:

Overview of Web Services Invocation

Invoking a Web service refers to the actions that a client application performs to use the Web service. Client applications that invoke Web services can be written using any technology: Java, Microsoft .NET, and so on.

There are two types of client applications:

  • Java SE client—In its simplest form, a Java SE client is a Java program that has the Main public class that you invoke with the java command.

  • Java EE component deployed to WebLogic Server—In this type of client application, the Web service runs inside a Java Platform, Enterprise Edition (Java EE) Version 5 component deployed to WebLogic Server, such as an EJB, servlet, or another Web service. This type of client application, therefore, runs inside a WebLogic Server container.

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). For information about support for stand-alone Java applications that are running in an environment where WebLogic Server libraries are not available, see Using a Stand-Alone Client JAR File When Invoking Web Services.

The sections that follow describe how to use Oracle's implementation of the JAX-RPC specification to invoke a Web service from a Java client application. You can use this implementation to invoke Web services running on any application server, both WebLogic and non-WebLogic. In addition, you can create a client that runs as part of a WebLogic Server, or a stand-alone client that runs in an environment where WebLogic Server libraries are not available.

In addition to the command-line tools described in this section, you can use an IDE, such as Oracle JDeveloper, for proxy generation and testing. For more information, see "Using Oracle IDEs to Build Web Services" in Oracle Fusion Middleware Introducing WebLogic Web Services for Oracle WebLogic Server.

Note:

You cannot use a dynamic client to invoke a Web service operation that implements user-defined data types as parameters or return values. A dynamic client uses the JAX-RPC Call interface. Standard (static) clients use the Service and Stub JAX-RPC interfaces, which correctly invoke Web services that implement user-defined data types.

Invoking Web Services Using JAX-RPC

The Java API for XML based RPC (JAX-RPC) is a specification that defines the APIs used to invoke a Web service. WebLogic Server implements the JAX-RPC specification.

The following table briefly describes the core JAX-RPC interfaces and classes.

Table 6-1 JAX-RPC Interfaces and Classes

javax.xml.rpc Interface or Class Description

Service

Main client interface.

ServiceFactory

Factory class for creating Service instances.

Stub

Base class of the client proxy used to invoke the operations of a Web service.

Call

Used to dynamically invoke a Web service.

JAXRPCException

Exception thrown if an error occurs while invoking a Web service.


Examples of Clients That Invoke Web Services

WebLogic Server includes examples of creating and invoking WebLogic Web services in the WL_HOME/samples/server/examples/src/examples/webservices directory, where WL_HOME refers to the main WebLogic Server directory. For detailed instructions on how to build and run the examples, open the WL_HOME/samples/server/docs/index.html Web page in your browser and expand the WebLogic Server Examples->Examples->API->Web Services node.

Invoking a Web Service from a Java SE Client

Note:

As described in this section, 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). For information about support for stand-alone Java applications that are running in an environment where WebLogic Server libraries are not available, see Using a Stand-Alone Client JAR File When Invoking Web Services.

The following table summarizes the main steps to create a Java SE client that invokes a Web service.

Note:

It is assumed that you use Ant in your development environment to build your client application, compile Java files, and so on, and that you have an existing build.xml file that you want to update with Web services client tasks. For general information about using Ant in your development environment, see Creating the Basic Ant build.xml File. For a full example of a build.xml file used in this section, see Sample Ant Build File for a Java Client.

Table 6-2 Steps to Invoke a Web Service from a Java SE Client

#
Step Description

1

Set up the environment.

Open a command window and execute the setDomainEnv.cmd (Windows) or setDomainEnv.sh (UNIX) command, located in the bin subdirectory of your domain directory. The default location of WebLogic Server domains is MW_HOME/user_projects/domains/domainName, where MW_HOME is the top-level installation directory of the Oracle products and domainName is the name of your domain.

2

Update your build.xml file to execute the clientgen Ant task to generate the needed client-side artifacts to invoke a Web service.

See Using the clientgen Ant Task To Generate Client Artifacts.

3

Get information about the Web service, such as the signature of its operations and the name of the ports.

See Getting Information About a Web Service.

4

Write the client application Java code that includes code for invoking the Web service operation.

See Writing the Java Client Application Code to Invoke a Web Service.

5

Create a basic Ant build file, build.xml.

See Creating the Basic Ant build.xml File.

6

Compile and run your Java client application.

See Compiling and Running the Client Application.


Using the clientgen Ant Task To Generate Client Artifacts

The clientgen WebLogic Web services Ant task generates, from an existing WSDL file, the client artifacts that client applications use to invoke both WebLogic and non-WebLogic Web services. These artifacts include:

  • The Java class for the JAX-RPC Stub and Service interface implementations for the particular Web service you want to invoke.

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

  • The JAX-RPC mapping deployment descriptor file which contains information about the mapping between the Java user-defined data types and their corresponding XML Schema types in the WSDL file.

  • A client-side copy of the WSDL file.

For additional information about the clientgen Ant task, such as all the available attributes, see "Ant Task Reference" in the Oracle Fusion Middleware WebLogic Web Services Reference for Oracle WebLogic Server.

Update your build.xml file, adding a call to the clientgen Ant task, as shown in the following example:

  <taskdef name="clientgen"
      classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
   <target name="build-client">
      <clientgen
        wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
        destDir="clientclasses"
        packageName="examples.webservices.simple_client"
        type="JAXRPC"/>
   </target>

Before you can execute the clientgen WebLogic Web service Ant task, you must specify its full Java classname using the standard taskdef Ant task.

You must include the wsdl and destDir attributes of the clientgen Ant task to specify the WSDL file from which you want to create client-side artifacts and the directory into which these artifacts should be generated. The packageName attribute is optional; if you do not specify it, the clientgen task uses a package name based on the targetNamespace of the WSDL. The type is also optional; if not specified, it defaults to JAXRPC.

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;

Note:

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 Oracle Fusion Middleware WebLogic Web Services Reference for Oracle WebLogic Server.

If the WSDL file specifies that user-defined data types are used as input parameters or return values of Web service operations, clientgen automatically generates a JavaBean class that is the Java representation of the XML Schema data type defined in the WSDL. The JavaBean classes are generated into the destDir directory.

Note:

The package of the Java user-defined data type is based on the XML Schema of the data type in the WSDL, which is different from the package name of the JAX-RPC stubs.

For a full sample build.xml file that contains additional targets from those described in this procedure, such as clean, see Sample Ant Build File for a Java Client.

To execute the clientgen Ant task, along with the other supporting Ant tasks, specify the build-client target at the command line:

prompt> ant build-client

See the clientclasses directory to view the files and artifacts generated by the clientgen Ant task.

Getting Information About a Web Service

You need to know the name of the Web service and the signature of its operations before you write your Java client application code to invoke an operation. There are a variety of ways to find this information.

The best way to get this information is to use the clientgen Ant task to generate the Web service-specific JAX-RPC stubs and look at the generated *.java files. These files are generated into the directory specified by the destDir attribute, with subdirectories corresponding to either the value of the packageName attribute, or, if this attribute is not specified, to a package based on the targetNamespace of the WSDL.

  • The ServiceName.java source file contains the getPortName() methods for getting the Web service port, where ServiceName refers to the name of the Web service and PortName refers to the name of the port. If the Web service was implemented with a JWS file, the name of the Web service is the value of the serviceName attribute of the @WebService JWS annotation and the name of the port is the value of the portName attribute of the @WLHttpTransport annotation.

  • The PortType.java file contains the method signatures that correspond to the public operations of the Web service, where PortType refers to the port type of the Web service. If the Web service was implemented with a JWS file, the port type is the value of the name attribute of the @WebService JWS annotation.

You can also examine the actual WSDL of the Web service; see Browsing to the WSDL of the Web Service for details about the WSDL of a deployed WebLogic Web service. The name of the Web service is contained in the <service> element, as shown in the following excerpt of the TraderService WSDL:

  <service name="TraderService">
     <port name="TraderServicePort"
          binding="tns:TraderServiceSoapBinding">
   ...
     </port>
   </service>

The operations defined for this Web service are listed under the corresponding <binding> element. For example, the following WSDL excerpt shows that the TraderService Web service has two operations, buy and sell (for clarity, only relevant parts of the WSDL are shown):

  <binding name="TraderServiceSoapBinding" ...>
     ...
     <operation name="sell">
     ...
     </operation>
     <operation name="buy">
     </operation>
   </binding>

Writing the Java Client Application Code to Invoke a Web Service

In the following code example, a Java application invokes a Web service operation. The client application takes a single argument: the WSDL of the Web service.The application then uses standard JAX-RPC API code and the Web service-specific implementation of the Service interface, generated by clientgen, to invoke an operation of the Web service.

The example also shows how to invoke an operation that has a user-defined data type (examples.webservices.complex.BasicStruct) as an input parameter and return value. The clientgen Ant task automatically generates the Java code for this user-defined data type.

package examples.webservices.simple_client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
// import the BasicStruct class, used as a param and return value of the
 // echoComplexType operation.  The class is generated automatically by
 // the clientgen Ant task.
import examples.webservices.complex.BasicStruct;
/**
  * This is a simple Java client application that invokes the
  * the echoComplexType operation of the ComplexService Web service.
  */
public class Main {
  public static void main(String[] args)
       throws ServiceException, RemoteException { 
    ComplexService service = new ComplexService_Impl (args[0] + "?WSDL" );
     ComplexPortType port = service.getComplexServicePort();
    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());
   }
 }

In the preceding example:

  • The following code shows how to create a ComplexPortType stub:

    ComplexService service = new ComplexService_Impl (args[0] + "?WSDL");
     ComplexPortType port = service.getComplexServicePort();
    

    The ComplexService_Impl stub factory implements the JAX-RPC Service interface. The constructor of ComplexService_Impl creates a stub based on the provided WSDL URI (args[0] + "?WSDL"). The getComplexServicePort() method is used to return an instance of the ComplexPortType stub implementation.

  • The following code shows how to invoke the echoComplexType operation of the ComplexService Web service:

    BasicStruct result = port.echoComplexType(in);
    

    The echoComplexType operation returns the user-defined data type called BasicStruct.

The method of your application that invokes the Web service operation must throw or catch java.rmi.RemoteException and javax.xml.rpc.ServiceException, both of which are thrown from the generated JAX-RPC stubs.

Compiling and Running the Client Application

Add javac tasks to the build-client target in the build.xml file to compile all the Java files (both of your client application and those generated by clientgen) into class files, as shown by the bold text in the following example:

  <target name="build-client">
    <clientgen
       wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
       destDir="clientclasses"
       packageName="examples.webservices.simple_client"
       type="JAXRPC"/>
    <javac
       srcdir="clientclasses" 
       destdir="clientclasses"
       includes="**/*.java"/>
    <javac
       srcdir="src" 
       destdir="clientclasses"
       includes="examples/webservices/simple_client/*.java"/>
  </target>

In the example, the first javac task compiles the Java files in the clientclasses directory that were generated by clientgen, and the second javac task compiles the Java files in the examples/webservices/simple_client subdirectory of the current directory; where it is assumed your Java client application source is located.

In the preceding example, the clientgen-generated Java source files and the resulting compiled classes end up in the same directory (clientclasses). Although this might be adequate for prototyping, it is often a best practice to keep source code (even generated code) in a different directory from the compiled classes. To do this, set the destdir for both javac tasks to a directory different from the srcdir directory. You must also copy the following clientgen-generated files from clientgen's destination directory to javac's destination directory, keeping the same subdirectory hierarchy in the destination:

packageName/ServiceName_internaldd.xml
packageName/ServiceName_java_wsdl_mapping.xml
packageName/ServiceName_saved_wsdl.wsdl

where packageName refers to the subdirectory hierarchy that corresponds to the package of the generated JAX-RPC stubs and ServiceName refers to the name of the Web service.

To run the client application, add a run target to the build.xml that includes a call to the java task, as shown below:

<path id="client.class.path">
     <pathelement path="clientclasses"/>
     <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"/>
   <arg line="http://${wls.hostname}:${wls.port}/complex/ComplexService" />
 </target>

The path task adds the clientclasses directory to the CLASSPATH. The run target invokes the Main application, passing it the URL of the deployed Web service as its single argument.

See Sample Ant Build File for a Java Client for a full sample build.xml file that contains additional targets from those described in this procedure, such as clean.

Rerun the build-client target to regenerate the artifacts and recompile into classes, then execute the run target to invoke the echoStruct operation:

    prompt> ant build-client run

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 Ant Build File for a Java Client

The following example shows a complete build.xml file for generating and compiling a Java client. See Using the clientgen Ant Task To Generate Client Artifacts and Compiling and Running the Client Application for explanations of the sections in bold.

<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
       wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
       destDir="${clientclass-dir}"
       packageName="examples.webservices.simple_client"
       type="JAXRPC"/>
    <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"/>
       <arg  line="http://${wls.hostname}:${wls.port}/complex/ComplexService"
       />
     </java>
   </target>
</project>

Invoking a Web Service from Another Web Service

Invoking a Web service from within a WebLogic Web service is similar to invoking one from another Java application, as described in Invoking a Web Service from a Java SE Client. However, instead of using the clientgen Ant task to generate the JAX-RPC stubs of the Web service to be invoked, you use the <clientgen> child element of the <jws> element, inside the jwsc Ant task that compiles the invoking Web service. In the JWS file that invokes the other Web service, however, you still use the same standard JAX-RPC APIs to get Service and PortType instances to invoke the Web service operations.

It is assumed that you have read and understood Invoking a Web Service from a Java SE Client. It is also assumed that you use Ant in your development environment to build your client application, compile Java files, and so on, and that you have an existing build.xml that builds a Web service that you want to update to invoke another Web service.

The following list describes the changes you must make to the build.xml file that builds your client Web service, which will invoke another Web service. See Sample build.xml File for a Web Service Client for the full sample build.xml file:

  • Add a <clientgen> child element to the <jws> element that specifies the JWS file that implements the Web service that invokes another Web service. Set the required wsdl attribute to the WSDL of the Web service to be invoked. Set the required packageName attribute to the package into which you want the JAX-RPC client stubs to be generated.

The following list describes the changes you must make to the JWS file that implements the client Web service; see Sample JWS File That Invokes a Web Service for the full JWS file example.

  • Import the files generated by the <clientgen> child element of the jwsc Ant task. These include the JAX-RPC stubs of the invoked Web service, as well as the Java representation of any user-defined data types used as parameters or return values in the operations of the invoked Web service.

    Note:

    The user-defined data types are generated into a package based on the XML Schema of the data type in the WSDL, not in the package specified by clientgen. The JAX-RPC stubs, however, use the package name specified by the packageName attribute of the <clientgen> element.

  • Update the method that contains the invoke of the Web service to either throw or catch both java.rmi.RemoteException and javax.xml.rpc.ServiceException.

  • Get the Service and PortType JAX-RPC stubs implementation and invoke the operation on the port as usual; see Writing the Java Client Application Code to Invoke a Web Service for details.

Sample build.xml File for a Web Service Client

The following sample build.xml file shows how to create a Web service that itself invokes another Web service; the relevant sections that differ from the build.xml for building a simple Web service that does not invoke another Web service are shown in bold.

The build-service target in this case is very similar to a target that builds a simple Web service; the only difference is that the jwsc Ant task that builds the invoking Web service also includes a <clientgen> child element of the <jws> element so that jwsc also generates the required JAX-RPC client stubs.

<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="JAXRPC">
           <clientgen
                 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="JAXRPC"/>
    <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"/>
           <arg
             line="http://${wls.hostname}:${wls.port}/ClientService/ClientService"/>
    </java>
  </target>
</project>

Sample JWS File That Invokes a Web Service

The following sample JWS file, called ClientServiceImpl.java, implements a Web service called ClientService that has an operation that in turn invokes the echoComplexType operation of a Web service called ComplexService. This operation has a user-defined data type (BasicStruct) as both a parameter and a return value. The relevant code is shown in bold and described after the example.

package examples.webservices.service_to_service;
import java.rmi.RemoteException;
 import javax.xml.rpc.ServiceException;
import javax.jws.WebService;
 import javax.jws.WebMethod;
import weblogic.jws.WLHttpTransport;
// Import the BasicStruct data type, generated by clientgen and used
 // by the ComplexService Web Service
import examples.webservices.complex.BasicStruct;
// Import the JAX-RPC Stubs for invoking the ComplexService Web Service.
 // Stubs generated by clientgen
import examples.webservices.service_to_service.ComplexPortType;
 import examples.webservices.service_to_service.ComplexService_Impl;
 import examples.webservices.service_to_service.ComplexService;
@WebService(name="ClientPortType", serviceName="ClientService",
             targetNamespace="http://examples.org")
@WLHttpTransport(contextPath="ClientService", serviceUri="ClientService",
                  portName="ClientServicePort")
public class ClientServiceImpl {
  @WebMethod()
   public String callComplexService(BasicStruct input, String serviceUrl) 
       throws ServiceException, RemoteException
   {
    // Create service and port stubs to invoke ComplexService
     ComplexService service = new ComplexService_Impl(serviceUrl + "?WSDL");
     ComplexPortType port = service.getComplexServicePort();
    // Create service and port stubs to invoke ComplexService
     ComplexService service = new ComplexService_Impl(serviceUrl + "?WSDL");
     ComplexPortType port = service.getComplexServicePortTypePort();
     // 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() + "'";
  }
 }

Follow these guidelines when programming the JWS file that invokes another Web service; code snippets of the guidelines are shown in bold in the preceding example:

  • Import any user-defined data types that are used by the invoked Web service. In this example, the ComplexService uses the BasicStruct JavaBean:

    import examples.webservices.complex.BasicStruct;
    
  • Import the JAX-RPC stubs of the ComplexService Web service; the stubs are generated by the <cliengen> child element of <jws>:

    import examples.webservices.service_to_service.ComplexPortType;
     import examples.webservices.service_to_service.ComplexService_Impl;
     import examples.webservices.service_to_service.ComplexService;
    
  • Ensure that your client Web service throws or catches ServiceException and RemoteException:

    throws ServiceException, RemoteException
    
  • Create the JAX-RPC Service and PortType instances for the ComplexService:

    ComplexService service = new 
          ComplexService_Impl(serviceUrl + "?WSDL");
     ComplexPortType port = service.getComplexServicePortTypePort();
    
  • Invoke the echoComplexType operation of ComplexService using the port you just instantiated:

    BasicStruct result = port.echoComplexType(input);
    

Using a Stand-Alone Client JAR File When Invoking Web Services

It is assumed in this document that, when you invoke a Web service using the client-side artifacts generated by the clientgen or wsdlc Ant tasks, you have the entire set of WebLogic Server classes in your CLASSPATH. If, however, your computer does not have WebLogic Server installed, you can still invoke a Web service by using the stand-alone WebLogic Web services client JAR file, as described in this section.

The standalone client JAR file supports basic client-side functionality, such as:

  • Use with client-side artifacts created by both the clientgen Ant tasks

  • Processing SOAP messages

  • Using client-side SOAP message handlers

  • Using MTOM

  • Invoking JAX-RPC Web services

  • Using SSL

The stand-alone client JAR file does not, however, support invoking Web services that use the following advanced features:

  • Web services reliable SOAP messaging

  • Message-level security (WS-Security)

  • Conversations

  • Asynchronous request-response

  • Buffering

  • JMS transport

To use the stand-alone WebLogic Web services client JAR file with your client application, follow these steps:

  1. Copy the file WL_HOME/server/lib/wseeclient.zip from the computer hosting WebLogic Server to the client computer, where WL_HOME refers to the WebLogic Server installation directory, such as /Oracle/Middleware/wlserver_10.3.

  2. Unzip the wseeclient.zip file into the appropriate directory. For example, you might unzip the file into a directory that contains other classes used by your client application.

  3. Add the wseeclient.jar file (unzipped from the wseeclient.zip file) to your CLASSPATH.

    Note:

    Also be sure that your CLASSPATH includes the JAR file that contains the Ant classes (ant.jar). This JAR file is typically located in the lib directory of the Ant distribution.

Using a Proxy Server When Invoking a Web Service

You can use a proxy server to proxy requests from a client application to an application server (either WebLogic or non-WebLogic) that hosts the invoked Web service. You typically use a proxy server when the application server is behind a firewall. There are two ways to specify the proxy server in your client application: programmatically using the WebLogic HttpTransportInfo API or using system properties.

Using the HttpTransportInfo API to Specify the Proxy Server

You can programmatically specify within the Java client application itself the details of the proxy server that will proxy the Web service invoke by using the standard java.net.* classes and the WebLogic-specific HttpTransportInfo API. You use the java.net classes to create a Proxy object that represents the proxy server, and then use the WebLogic API and properties to set the proxy server on the JAX-RPC stub, as shown in the following sample client that invokes the echo operation of the HttpProxySampleService Web service. The code in bold is described after the example:

package dev2dev.proxy.client;
import java.net.Proxy;
 import java.net.InetSocketAddress;
import weblogic.wsee.connection.transport.http.HttpTransportInfo;
/**
  * Sample client to invoke a service through a proxy server via 
  * programmatic API
  */
public class HttpProxySampleClient {
   public static void main(String[] args) throws Throwable{
     assert args.length == 5;
     String endpoint = args[0];
     String proxyHost = args[1];
     String proxyPort = args[2];
     String user = args[3];
     String pass = args[4];
    //create service and port
     HttpProxySampleService service = new HttpProxySampleService_Impl();
     HttpProxySamplePortType port = service.getHttpProxySamplePortTypeSoapPort();
    //set endpoint address
     ((Stub)port)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endpoint);
    //set proxy server info
    Proxy p = new Proxy(Proxy.Type.HTTP, new  InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
     HttpTransportInfo info = new HttpTransportInfo();
     info.setProxy(p);
     ((Stub)port)._setProperty("weblogic.wsee.connection.transportinfo",info);
    //set proxy-authentication info
     ((Stub)port)._setProperty("weblogic.webservice.client.proxyusername",user);
     ((Stub)port)._setProperty("weblogic.webservice.client.proxypassword",pass);
    //invoke
     String s = port.echo("Hello World!");
     System.out.println("echo: " + s);
   }
 }

The sections of the preceding example to note are as follows:

  • Import the required java.net.* classes:

    import java.net.Proxy;
     import java.net.InetSocketAddress;
     
    
  • Import the WebLogic HttpTransportInfo API:

    import weblogic.wsee.connection.transport.http.HttpTransportInfo;
     
    
  • Create a Proxy object that represents the proxy server:

    Proxy p = new Proxy(Proxy.Type.HTTP, new  InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
     
    

    The proxyHost and proxyPort arguments refer to the host computer and port of the proxy server.

  • Create an HttpTransportInfo object and use the setProxy() method to set the proxy server information:

    HttpTransportInfo info = new HttpTransportInfo();
     info.setProxy(p);
     
    
  • Use the weblogic.wsee.connection.transportinfo WebLogic stub property to set the HttpTransportInfo object on the JAX-RPC stub:

    ((Stub)port)._setProperty("weblogic.wsee.connection.transportinfo",info);
     
    
  • Use weblogic.webservice.client.proxyusername and weblogic.webservice.client.proxypassword WebLogic-specific stub properties to specify the username and password of a user who is authenticated to access the proxy server:

    ((Stub)port)._setProperty("weblogic.webservice.client.proxyusername",user);
         ((Stub)port)._setProperty("weblogic.webservice.client.proxypassword",pass);
     
    

    Alternatively, you can use the setProxyUsername() and setProxyPassword() methods of the HttpTransportInfo API to set the proxy username and password, as shown in the following example:

        info.setProxyUsername("juliet".getBytes());
         info.setProxyPassword("secret".getBytes());
     
    

Using System Properties to Specify the Proxy Server

To use system properties to specify the proxy server, write your client application in the standard way, and then specify system properties when you execute the client application.

You have a choice of using standard Java system properties or historical WebLogic properties. If the proxySet system property is set to false (proxySet=false), proxy properties will be ignored and no proxy will be used.

The following table summarizes the Java system properties. In this case, the proxySet system property must not be set.

Table 6-3 Java System Properties Used to Specify Proxy Server

Property Description

http.proxyHost=proxyHost

or

https.proxyHost=proxyHost

Name of the host computer on which the proxy server is running. Use https.proxyHost for HTTP over SSL.

http.proxyPort=proxyPort

or

https.proxy.Port=proxyPort

Port to which the proxy server is listening. Use https.proxyPort for HTTP over SSL.

http.nonProxyHosts=

hostname | hostname | ...

List of hosts that should be reached directly, bypassing the proxy. Separate each host name using a | character. This property applies to both HTTP and HTTPS.


The following excerpt from an Ant build script shows an example of setting Java system properties when invoking a client application called clients.InvokeMyService:

  <target name="run-client">
     <java fork="true"
           classname="clients.InvokeMyService"
           failonerror="true">
       <classpath refid="client.class.path"/>
       <arg line="${http-endpoint}"/>
       <jvmarg line=
         "-Dhttp.proxyHost=${proxy-host} 
         -Dhttp.proxyPort=${proxy-port}
         -Dhttp.nonProxyHosts=${mydomain}"
       />
     </java>
   </target>

The following table summarizes the WebLogic system properties. In this case, the proxySet system property must be set to true.

Table 6-4 WebLogic System Properties Used to Specify the Proxy Server

Property Description

proxySet=true

Flag that specifies that the historical WebLogic proxy properties should be used.

proxyHost=proxyHost

Name of the host computer on which the proxy server is running.

proxyPort=proxyPort

Port to which the proxy server is listening.

weblogic.webservice.client.proxyusername=username

Username used to access the proxy server.

weblogic.webservice.client.proxypassword=password

Password used to access the proxy server.


The following excerpt from an Ant build script shows an example of setting WebLogic system properties when invoking a client application called clients.InvokeMyService:

  <target name="run-client">
     <java fork="true"
           classname="clients.InvokeMyService"
           failonerror="true">
       <classpath refid="client.class.path"/>
       <arg line="${http-endpoint}"/>
       <jvmarg line=
        "-DproxySet=true 
         -DproxyHost=${proxy-host} 
         -DproxyPort=${proxy-port}
         -Dweblogic.webservice.client.proxyusername=${proxy-username}
         -Dweblogic.webservice.client.proxypassword=${proxy-passwd}"
       />
     </java>
   </target>

Client Considerations When Redeploying a Web Service

WebLogic Server supports production redeployment, which means that you can deploy a new version of an updated WebLogic Web service alongside an older version of the same Web service.

WebLogic Server automatically manages client connections so that only new client requests are directed to the new version. Clients already connected to the Web service during the redeployment continue to use the older version of the service until they complete their work, at which point WebLogic Server automatically retires the older Web service. If the client is connected to a conversational or reliable Web service, its work is considered complete when the existing conversation or reliable messaging sequence is explicitly ended by the client or because of a timeout.

You can continue using the old client application with the new version of the Web service, as long as the following Web service artifacts have not changed in the new version:

  • WSDL that describes the Web service

  • WS-Policy files attached to the Web service

If any of these artifacts have changed, you must regenerate the JAX-RPC stubs used by the client application by re-running the clientgen Ant task.

For example, if you change the signature of an operation in the new version of the Web service, then the WSDL file that describes the new version of the Web service will also change. In this case, you must regenerate the JAX-RPC stubs. If, however, you simply change the implementation of an operation, but do not change its public contract, then you can continue using the existing client application.

WebLogic Web Services Stub Properties

WebLogic Server provides a set of stub properties that you can set in the JAX-RPC Stub used to invoke a WebLogic Web service. Use the Stub._setProperty() method to set the properties, as shown in the following example:

((Stub)port)._setProperty(WLStub.MARSHAL_FORCE_INCLUDE_XSI_TYPE,"true");
 

Most of the stub properties are defined in the WLStub class. See "weblogic.wsee.jaxrpc.WLStub" in the Oracle Fusion Middleware Oracle WebLogic Server API Referencefor details.

The following table describes additional stub properties not defined in the WLStub class.

Table 6-5 Additional Stub Properties

Stub Property Description
weblogic.wsee.transport.connection.timeout

Specifies, in milliseconds, how long a client application that is attempting to invoke a Web service waits to make a connection. After the specified time elapses, if a connection hasn't been made, the attempt times out.

weblogic.wsee.transport.read.timeout

Specifies, in milliseconds, how long a client application waits for a response from a Web service it is invoking. After the specified time elapses, if a response hasn't arrived, the client times out.

weblogic.wsee.security.bst.serverVerifyCert

Specifies the certificate that the client application uses to validate the signed response from WebLogic Server. By default, WebLogic Server includes the certification used to validate in the response SOAP message itself; if this is not possible, then use this stub property to specify a different one.

This stub property applies only to client applications that run inside of a WebLogic Server container, and not to stand-alone client applications.

The value of the property is an object of data type java.security.cert.X509Certificate.

weblogic.wsee.security.bst.serverEncryptCert

Specifies the certificate that the client application uses to encrypt the request SOAP message sent to WebLogic Server. By default, the client application uses the public certificate published in the Web service's WSDL; if this is not possible, then use this stub property to specify a different one.

This stub property applies only to client applications that run inside of a WebLogic Server container, and not to stand-alone client applications.

The value of the property is an object of data type java.security.cert.X509Certificate.

weblogic.wsee.marshal.forceIncludeXsiType

Specifies that the SOAP messages for a Web service operation invoke should include the XML Schema data type of each parameter. By default, the SOAP messages do not include the data type of each parameter.

If you set this property to True, the elements in the SOAP messages that describe operation parameters will include an xsi:type attribute to specify the data type of the parameter, as shown in the following example:

<soapenv:Envelope>
 ...
  <maxResults xsi:type="xs:int">10</maxResults>
 ...

By default (or if you set this property to False), the parameter element would look like the following example:

<soapenv:Envelope>
 ...
  <maxResults>10</maxResults>
 ...

Valid values for this property are True and False; default value is False.


Setting the Character Encoding For the Response SOAP Message

Use the weblogic.wsee.jaxrpc.WLStub.CHARACTER_SET_ENCODING WLStub property to set the character encoding of the response (outbound) SOAP message. You can set it to the following two values:

  • UTF-8

  • UTF-16

The following code snippet from a client application shows how to set the character encoding to UTF-16:

  Simple port = service.getSimpleSoapPort();
   ((Stub) port)._setProperty(weblogic.wsee.jaxrpc.WLStub.CHARACTER_SET_ENCODING, "UTF-16");
   port.invokeMethod();

See "weblogic.wsee.jaxrpc.WLStub" in the Oracle Fusion Middleware Oracle WebLogic Server API Reference for additional WLStub properties you can set.