![]() ![]() ![]() ![]() ![]() ![]() |
The following sections describe how to invoke WebLogic Web Services:
Note: | The following sections do not include information about invoking message-secured Web Services; for that topic, see “Updating a Client Application to Invoke a Message-Secured Web Service” in Securing WebLogic Web Services. |
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:
Main
public class that you invoke with the java
command. It runs completely separately from WebLogic Server.The sections that follow describe how to use Oracle’s implementation of the JAX-WS 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 stand-alone client application or one that runs as part of a WebLogic Server.
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.
The following table summarizes the main steps to create a stand-alone client that invokes a Web Service. See also Using a Stand-Alone Client JAR File When Invoking Web Services.
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 Stand-Alone Java Client. |
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:
For additional information about the clientgen
Ant task, such as all the available attributes, see
“Ant Task Reference” in the WebLogic Web Services Reference.
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="JAXWS"/>
</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 required in this example; otherwise, 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 WebLogic Web Services Reference. |
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.
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 Stand-Alone 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.
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 Service
files 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.
ServiceName
.java
source file contains the get
PortName
()
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>
child element of the <jws>
element of the jwsc
Ant task.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>
In the following code example, a stand-alone application invokes a Web Service operation. The application uses standard JAX-WS 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.simple_client.BasicStruct
) as an input parameter and return value. The clientgen
Ant task automatically generates the Java code for this user-defined data type.
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 stand-alone client application that invokes the
* 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());
}
}
ComplexPortType
stub:
ComplexService test = new ComplexService(),
ComplexPortType port = test.getComplexPortTypePort();
The ComplexService
class implements the JAX-WS Service
interface. The getComplexServicePortTypePort()
method is used to return an instance of the ComplexPortType
stub implementation.
echoComplexType
operation of the ComplexService
Web Service:BasicStruct result = port.echoComplexType(in);
The echoComplexType
operation returns the user-defined data type called BasicStruct.
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="JAXWS"/>
<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.
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"/>
</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 Stand-Alone 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.
The following example shows a complete build.xml
file for generating and compiling a stand-alone 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="JAXWS"/>
<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 within a WebLogic Web Service is similar to invoking one from a stand-alone Java application, as described in Invoking a Web Service from a Stand-alone Client: Main Steps, with the following variations:
clientgen
Ant task to generate the JAX-WS Service
interface 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-WS APIs to get Service
and PortType
instances to invoke the Web Service operations.@WebServiceRef
annotation to define a reference to a Web Service, as described in Defining a Web Service Reference Using the @WebServiceRef Annotation.
This section describes the differences between invoking a Web Service from a client in a Java EE component and invoking from a stand-alone client. It is assumed that you have read and understood Invoking a Web Service from a Stand-alone Client: Main Steps. 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:
<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-WS 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.
<clientgen>
child element of the jwsc
Ant task. These include the JAX-WS Service
interface 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: | If the package name set using the packageName attribute of <clientgen> is set to the same package name as the client application, then you are not required to import the <clientgen> -generated files. |
Service
and PortType
interface implementation and invoke the operation on the port as usual; see Writing the Java Client Application Code to Invoke a Web Service for details.
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="JAXWS">
<clientgen
</jws>
wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
packageName="examples.webservices.complex" />
</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>
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 javax.jws.WebService;
import javax.jws.WebMethod;
// 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 for invoking the ComplexService Web Service.
// Stubs generated by clientgen
import examples.webservices.complex.ComplexPortType;
import examples.webservices.complex.ComplexService;
@WebService(name="ClientPortType", serviceName="ClientService",
targetNamespace="http://examples.org")
public class ClientServiceImpl {
@WebMethod()
public String callComplexService(BasicStruct input, String serviceUrl)
{
// Create service and port stubs to invoke ComplexService
ComplexService test = new 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() + "'";
}
}
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:
ComplexService
uses the BasicStruct
JavaBean:import examples.webservices.complex.BasicStruct;
ComplexService
Web Service; the stubs are generated by the <cliengen>
child element of <jws>
:import examples.webservices.complex.ComplexPortType;
import examples.webservices.complex.ComplexService;
Service
and PortType
instances for the ComplexService
:ComplexService test = new ComplexService();
ComplexPortType port = test.getComplexPortTypePort();
echoComplexType
operation of ComplexService
using the port you just instantiated:BasicStruct result = port.echoComplexType(input);
The @WebServiceRef
annotation enables you to define a reference to a Web Service. For example, in the following sample, a reference to the ComplexService
is defined by passing the WSDL of the Web Service to the @WebServiceRef
annotation.
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 interfaces for invoking the ComplexService Web Service.
// Interfaces generated by clientgen
import examples.webservices.complex.ComplexPortType;
import examples.webservices.complex.ComplexService;
@WebService(name="ClientPortType", serviceName="ClientService",
targetNamespace="http://examples.org")
public class ClientServiceImpl {
@WebServiceRef()
ComplexService service;
@WebMethod()
public String callComplexService(BasicStruct input)
{
// Create service and port stubs to invoke ComplexService
ComplexPortType port = service.getComplexPortTypePort();
// Invoke the echoComplexType operation of ComplexServiceBasicStruct result = port.echoComplexType(input);
System.out.println("Invoked ComplexPortType.echoComplexType." );
return "Invoke went okay! Here's the result: '" + result.getIntValue() + ", " + result.getStringValue() + "'";
}
}
@WebServiceRef
annotation is used to define a reference to a Web Service and an injection target for it:@WebServiceRef()
ComplexService service;
ComplexPortType
stub implementation using the Web Service reference:ComplexPortType port = service.getComplexPortTypePort();
sayHello
operation of the ComplexService
Web Service:BasicStruct result = port.echoComplexType(input);
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:
The stand-alone client JAR file does not, however, support invoking Web Services that use the following advanced feature:
To use the stand-alone WebLogic Web Services client JAR file with your client application, follow these steps:
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 /bea/wlserver_10.3
.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.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. |
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.
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:
If any of these artifacts have changed, you must regenerate the JAX-WS 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-WS 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.
![]() ![]() ![]() |