![]() ![]() ![]() ![]() ![]() ![]() |
Web services provide an industry-standard way to develop SOA (service-oriented architecture) applications. Such services can be thought of as loosely coupled, distributed units of programming logic that can be re-configured easily to deliver new application functionality, both intra- and extra-enterprise.
Using Web services and BEA AquaLogic Data Services Platform allow your applications to better leverage enterprise data assets.
This chapter explains you how to expose data services as standard Web services, and how to create client applications that can obtain the benefits of both Web services and SDOs. It covers these topics:
For more information about Web services, see:
http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webservices.html
Exposing data services as Web services makes your information assets accessible to a wide variety of client types, including other Java Web service clients, Microsoft ADO.NET and other non-Java applications, and other Web services. Figure 4-1 illustrates the various approaches that client application developers can take to integrating data services and Web services.
Note: | For information about ADO.NET-enabled Web services and client applications, see Supporting ADO.NET Clients.. |
Data services can be integrated with Web services in one of two general ways:
Note: | For details on working with static and dynamic SDOs see Static and Dynamic Data APIs. |
Figure 4-2 shows the end-to-end process — both the server-side and client-side tasks — that expose a AquaLogic Data Services Platform-enabled application as a Web service and implement a client application that invokes operations on that service.
AquaLogic Data Services Platform-enabled Web service development depends on whether you are working with read-only Web services or Web services which support read-write functionality.
There are two ways to create Web services from data services. By:
Both approaches rely on Data Service controls as the component-based integration mechanism.
You can easily add one or more Data Service controls to a Web service using WebLogic Workshop. Firstcreate a folder for the controls inside the Web service's project folder, and then create the Data Service controls.
You can also create controls during the process of adding them to the Web service but, for simplicity's sake, the instructions in this section assume that you have created the Data Service controls in advance. (See Creating Data Service Controls for more information on creating Data Service controls.)
Leave the checkbox labeled Make This a Control Factory unselected. (This checkbox would cause the Data Service control to be instantiated at runtime using the factory pattern, rather than as a singleton. To use the control in a Web service, it must be a singleton.)
LiquidDataControl.jar
file is copied into the Libraries directory of the application. The variable you created in STEP 1 of the dialog displays as a node in the Data Palette, with its functions and procedures listed under the node. It is these functions and procedures that you can now expose to client applications, by adding them to the Web service's callable interface (shown as the left-hand portion of the Web service's Design View in WebLogic Workshop — see Figure 4-5), as described in the next step.
You can test your Web service as described in Testing a Web Service in WebLogic Workshop. After testing, you can deploy your Web service to a production WebLogic server and use it as you would any other Web service. For information about developing Java-based Web service clients, see Client-Side AquaLogic Data Services Platform-Enabled Web Service Development.
Another way to create a AquaLogic Data Services Platform-enabled Web service is by generating stateless Web services from Data Service controls. The generated Web services automatically include operations (method calls) for each of the functions and procedures that the Data Service control comprises.
Follow the instructions in this section to generate and test a stateless Web service. (These instructions assume that you have already created the Data Service control and that WebLogic Workshop is open.)
Note: | Although WebLogic Workshop by default generates Web services that have the word "Test" embedded in the file names, these are deployable Web services. You can rename the generated Web service to eliminate the word "Test". |
You will see methods (operations) for each of the functions and procedures contained in the Data Service control.
If your Web service must support submits from Java Web service clients, you first need to modify the JWS file before generating the WSDL, as follows:
For instance, if the original signature of the submit() method of the generated JWS looks appears as:
java.util.Properties[] submitCustomerProfile(CustomerProfileDocument doc);
It should be modified to the following:
java.util.Properties[] submitCustomerProfile(DatagraphDocument rootDataObject)
CustomerProfileDocument doc = (CustomerProfileDocument) new DataGraphImpl(rootDataObject).getRootObject();
return customerData.submitCustomerProfile(doc); //customerData is the AquaLogic Data Services Platform control
After you have created the WSDL file, provide it to your client application developers, so they can generate the Web services client interfaces and proxy code necessary (as discussed in Client-Side AquaLogic Data Services Platform-Enabled Web Service Development).
By default, WebLogic Workshop creates two operations in its generated Web services that can be used for testing purposes.
Continue developing the functionality of the Web service as required, testing as you go along. Once the Web service is complete, you can create the artifacts necessary for client application development, as described in the next section, Client-Side AquaLogic Data Services Platform-Enabled Web Service Development.
Note: | For more information about Web service client applications and WebLogic server in general, see Invoking Web Services in Programming WebLogic Web Services in WebLogic server documentation. |
Your client application uses either a static or a dynamic approach to Web services. Both approaches are discussed in this section. The following topics provide brief summaries of the appropriate client requirements.
A static Web service client requires:
AquaLogic Data Services Platform includes the necessary utilities (Java classes and Ant tasks) to generate the following classes for a static Web service client:
A typical static Web service client can use the following to retrieve a customer's record:
CUSTOMERDocument doc = wssoap.getCustomer("987654");
Note: | The wssoap class is an instance of the generated Web service client proxy class; the doc object is an instance of the generated Static SDO class named CUSTOMERDocument. |
A dynamic Web service client requires:
Note: | Neither the generated SDO classes, nor the Web service client proxy classes are needed for the Dynamic Web service client. |
A typical dynamic Web service client can retrieve a customer's record with the following:
XmlObject param = XmlObject.Factory.parse( "<msg:getCustomer xmlns:msg='http://www.openuri.org/'><CustomerID>987654</CustomerID></msg:getCustomer>");
DataObject doc = (DataObject)call.invoke(new Object[]{param});
Note: | The call class is an instance of the call interface of the JAX-RPC API. The doc object is an instance of the DataObject interface of the Dynamic SDO API. |
The following general steps are involved in developing a static Web service client for AquaLogic Data Services Platform:
As a prequisite to creating the AquaLogic Data Services Platform proxy, you first generate the necessary SDO classes.
You can generate SDO classes for your Web service client using an Ant task (sdogen) or through a Java class. Each method is described in this section.
The sdogen Ant task creates an SDO client JAR file that contains the typed classes needed for working with SDOs. The task either can use:
to extracted the needed typed classes.
In order to successfully run the sdogen task, make sure your classpath includes:
To create a JAR comprising the necessary client (SDO) classes, add the sdogen tas-kdef to your build script. For example:
<taskdef name="sdogen" classname="com.bea.sdo.impl.SDOGenTask" classpath="path/to/wlsdo.jar:path/to/xbean.jar"/>
where path/to is replaced with the physical location of your JAR files.
This task implicitly defines an Ant FileSet, and supports all FileSet attributes (for example, dir becomes basedir) as well as the nested attributes and elements. Table 4-7 summarizes the attributes used by the sdogen Ant task.
|
|||||
To build a WSDL or XML schema definition (XSD) files in the schemas directory and create a JAR named Schemas.jar
, your Ant script would need to include the following:
<sdogen schema="MyTestWS.WSDL" destfile="Schemas.jar" classpath="path/to/wlsdo.jar:path/to/xbean.jar"/>
where path/to represents the physical location of your JAR files.
You can use the SDOGen Java class at the command-line to generate SDO client classes from XML schema definition (XSD) files or WSDL files based on data services.
SDOGen is a Java class that extends the XMLBean schema compiler class. See Table 4-8 for command-line options for the SDOGen utility.
To execute the utility, make sure your classpath includes:
To create a JAR comprising the client classes, execute SDOGen at the command prompt as follows:
java com.bea.sdo.impl.SDOGen [options] XMLSchema
The following are examples of using SDOGen with various options (Table 4-8) to obtain different results:
xmltype.jar
(the default) based on the WSDL associated with Web service named MyApp running locally you can use:java com.bea.sdo.impl.SDOGen http://localhost:7001/WebApp/DSCtrls/MyApp.jws?WSDL
xmltype.jar
(the default) based on the WSDL associated with a publicly available Web service, use: java com.bea.sdo.impl.SDOGen -dl http://198.68.125.17:7001/WebApp/DSCtrls/MyApp.jws?WSDL
The -dl option permits downloading.
xmltype.jar
using an XML schema definition (a XSD file) located in the following directory on your local machine:\myApps\xsd_dir
java com.bea.sdo.impl.SDOGen C:\myApps\xsd_dir
MySDOClasses.jar
file in the c:\test\xsd_dir
directory you can use:java com.bea.sdo.impl.SDOGen -out MySDOClasses.jar C:\test\xsd_dir
You can generate an SDO Web client proxy using an Ant task (sdoclientgen) or invoke a Java class (WSClientGen) to perform the same task. Each approach is described in this section.
Using Ant to Generate Your Client Proxy
The sdoclientgen Ant task generates an SDO-enabled Web services client JAR file that your client applications can use to consume JWS files generated from a Data Service control.
Typically, you can generate a client JAR file from an existing WSDL file of the JWS.
The generated client JAR file includes:
Although you could use the sdoclientgen task to generate a client JAR file from the WSDL file of any existing Web service (not necessarily running on WebLogic server), the task typically is used to generate the JAR file from an existing WSDL file of an SDO-enabled JWS.
<taskdef name="sdoclientgen" classname="com.bea.sdo.impl.WSClientGenTask" classpath="path/to/SDOclasses:path/to/wlsdo.jar:path/to/xbean.jar:path/to/wlxbean.jar:path/to/xqrl.jar:path/to/webservices.jar"/>
where path/to is replaced with the physical location of your JAR files.
Note: | See also Sample Script for Creating a Static Web Service Client. |
The WebLogic server distribution includes a client runtime JAR file (webserviceclient.jar
) that contains the client-side classes needed to support the WebLogic Web services runtime component.
Table 4-9 describes sdoclientgen attributes.
Table 4-9 sdoclientgen Ant Task AttributesThe following Ant script provides a working sample illustrating the creation of a static Web service client. It generates all SDO and Web service client classes into a single JAR file, demonstrating the following:
- <project name="samplesdogen" default="build" basedir=".">
<property name="output.jar" value="MyTestClient.jar" />
<property name="wsdl.file" value="../DanubeCtrlTest.wsdl" />
<property name="local.build.dir" value="build" />
<property name="external.resource.dir" value="../../../../path to external resource" />
<mkdir dir="${local.build.dir}" />
- <path id="compile.classpath">
<pathelement path="${java.class.path}" />
<pathelement path="${local.build.dir}" />
<pathelement location="${external.resource.dir}/weblogic.jar" />
<pathelement location="${external.resource.dir}/xbean.jar" />
<pathelement location="${external.resource.dir}/wlxbean.jar" />
<pathelement location="${external.resource.dir}/xqrl.jar" />
<pathelement location="${external.resource.dir}/webservices.jar" />
<pathelement location="${external.resource.dir}/../src/ld-core/sdoUpdate/dist/wlsdo.jar" />
</path>
<taskdef name="sdogen" classname="com.bea.sdo.impl.SDOGenTask" classpathref="compile.classpath" />
<taskdef name="sdoclientgen" classname="com.bea.sdo.impl.WSClientGenTask" classpathref="compile.classpath" />
- <target name="sdo" depends="clean">
<sdogen classgendir="${local.build.dir}" schema="${wsdl.file}" classpath="${external.resource.dir}/../src/ld-core/sdoUpdate/dist/wlsdo.jar:${external.resource.dir}/xbean.jar" memoryInitialSize="8m" memoryMaximumSize="256m" fork="true" failonerror="true" />
</target>
- <target name="build" depends="sdo">
<sdoclientgen wsdl="${wsdl.file}" packageName="sdoclient" clientJar="${local.build.dir}/${output.jar}" classpathref="compile.classpath" />
- <jar jarfile="${local.build.dir}/${output.jar}" update="yes">
- <fileset dir="${local.build.dir}">
<exclude name="${output.jar}" />
</fileset>
</jar>
</target>
- <target name="clean">
<delete dir="${local.build.dir}" />
<mkdir dir="${local.build.dir}" />
</target>
</project>
In order to execute the sdoclientgen task, your classpath must include the following JAR files in the following order:
<bea_home>/weblogic81/server/lib
Define your Ant task for SDOClientGen as shown in this example:
<taskdef name="sdoclientgen" classname="com.bea.sdo.impl.WSClientGenTask" classpath="path/to/SDOclasses:path/to/wlsdo.jar:path/to/xbean.jar:path/to/wlxbean.jar:path/to/xqrl.jar:path/to/webservices.jar"/>
<sdoclientgen wsdl="http://example.com/myapp/myservice.wsdl" packageName="sdoclient" clientJar="myapps/mySDO_WSclient.jar" classpathref="all the JAR files listed in the task"/>
The Web Services Client Generation utility is a Java class (WSClientGen) that you can use to generate Web services client interfaces and stub classes from a WSDL that uses typed SDO classes for argument and return types.
The utility should be used to generate Web service clients that allow a client to consume a Web service (that is, a JWS file) from a Data Service control that invokes a AquaLogic Data Services Platform query or submit.
java com.bea.sdo.impl.WSClientGen [options] wsdl
The WSDL can be the URL of the WSDL (available over the network), or the actual, physical WSDL file located on your machine. Command-line options that you can pass to the utility are shown in Table 4-10.
Here are some examples of using the utility:
java com.bea.sdo.impl.WSClientGen http://localhost:7001/WebApp/DSCtrls/MyApp.jws?WSDL
MyClient.jar
(rather than the default), pass the file name with the -clientJar parameter at the command line:java com.bea.sdo.impl.WSClientGen -clientJar MyClient.jar http://localhost:7001/WebApp/DSCtrls/MyApp.jws?WSDL
The SDO Web Service Client Gen utility is an Ant build script that you can invoked from a command line to build SDO objects for the client. The script (including its pathname) is:
<bea_home>\weblogic81\liquiddata\bin\sdo_wsclientgen.xml
The WSDL file you created in the procedure described in Developing AquaLogic Data Services Platform-Enabled Read-Write Web Services is passed to the utility as a parameter, and the SDO objects generated by sdo_wsclientgen.xml are based on that file.
The configuration parameters for the Ant build script sdo_wsclientgen.xml are:
Before using the Ant script to build SDO classes, make sure you set your environment by calling the setWLSEnv.cmd
in the command prompt window. This command file is located in the directory:
$bea_home\weblogic81\server\bin
You must include the following packages in your client's CLASSPATH to work with SDO objects:
wlsdo.jar
webserviceclient.jar
xbean.jar
wlxbean.jar
xqrl.jar
The specific steps you need to perform with the Ant utility in order to build SDO classes are:
set CLASSPATH=
\bea\weblogic81\server\bin\setWLSEnv.cmd
\bea\weblogic81\samples\domains\ldplatform\setDomainEnv.cmd
Note: | This will change your current path; navigate back to the path for your application. |
mkdir sdotemp
set CLASSPATH=%CLASSPATH%;sdotemp
ant -buildfile <bea_home>\weblogic81\liquiddata\bin\sdo_wsclientgen.xml -Dwsdl path/to/nameOfWSDL.wsdl
where sdo_wsclientgen.xml
is a build file packaged with your weblogic installation and path/to represents the physical location of your wsdl file. For example:
ant -buildfile D:\bea\weblogic81\samples\liquiddata\bin\sdo_wsclientgen.xml -Dwsdl D:\bea\weblogic81\samples\liquiddata\RTLApp\StaticWebService\controls\CustomerProfileJWSContract.wsdl
After using the Ant utility (that is by issuing the command, ant sdo_wsclientget.xml), a JAR file is created; among other generated artifacts, the JAR file contains the typed SDO classes. You can distribute the JAR files to all clients that will consume operations from this Web service.
After running the Ant utility, you can call the modified submit operation that you created in step 2 of the procedure described in Developing AquaLogic Data Services Platform-Enabled Read-Write Web Services. For example, your client code would be as follows, based on the submitCustomerProfile method shown in step 2, above:
CustomerDataTestSoap wssoap = new CustomerDataTest_Impl().getCustomerDataTestSoap();
CustomerProfileDocument doc = wssoap.getCustomerProfile(customer_id);
doc.getCustomerProfile().getCustomerArray(0).setLastName("Test");
DataGraphImpl dg = (DataGraphImpl) doc.getDataGraph();
wssoap.submitCustomerProfile(dg.getSerializedDocument());
The following instructions enable you to set up your Web service client environment for AquaLogic Data Services Platform.
After generating the SDO Web service client classes in a JAR file (SDOClient.jar
), set up the classpath for the Web service client using the following JAR files in the following order:
If you are not already familiar with the concept of using a Web service client proxy or JAX-RPC API to invoke Web services, see Developing AquaLogic Data Services Platform-Enabled Read-Write Web Services.
Then, in developing your Web service client, follow these steps:
Alternatively, you can also use the dynamic SDO API to read or modify the data.
See Data Programming Model and Update Framework for details on handling insertions and deletions using the static and dynamic SDO APIs.
wssoap.submitCustomer(((DataGraphImpl)doc.getDataGraph()).getSerializedDocument());
The following code shows a sample Java static Web services client for AquaLogic Data Services Platform:
public class test_read_write_static {
public static void main(String[] args) throws Exception {
try {
CustomerProfileJWS ws = new CustomerProfileJWS_Impl();
CustomerProfileJWSSoap wssoap = ws.getCustomerProfileJWSSoap();
CUSTOMERPROFILEDocument cpdoc = wssoap.getCustomerByCustID("CUSTOMER1");
System.out.println(cpdoc);
cpdoc.getCUSTOMERPROFILE().setFirstName("Jack");
wssoap.submitCustomer(((com.bea.sdo.impl.DataGraphImpl)cpdoc.getDataGraph()).getSerializedDocument() );
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
Developing your dynamic Web services involves the following:
Set up the classpath for your Web service client using the following JAR files in the following order:
Note: | The order of files shown above must be maintained. |
There are three aspects to developing a dynamic Web service client. First the client must be created using standard development procedures. Then there are several AquaLogic Data Services Platform specific steps.
Follow the JAX-RPC instructions in JAX-RPC documentation ( http://java.sun.com/webservices/jaxrpc/docs.html) to create the framework for a dynamic Web services client. Essentially this work involves:
To enable the dynamic Web service for AquaLogic Data Services Platform you then need to:
Finally complete development by:
The following code (with comments emphasized) shows a complete Java dynamic Web services client for AquaLogic Data Services Platform, including import statements.
import com.bea.sdo.impl.DataGraphCodec;
import com.bea.xml.XmlObject;
import commonj.sdo.DataObject;
import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
public class TestCodecArray
{
public static void main(String args[]) throws Exception {
System.setProperty("javax.xml.soap.MessageFactory", "weblogic.webservice.core.soap.MessageFactoryImpl");
// Setup the global JAX-RPC service factory
System.setProperty( "javax.xml.rpc.ServiceFactory", "weblogic.webservice.core.rpc.ServiceFactoryImpl");
// create service factory
ServiceFactory factory = ServiceFactory.newInstance();
// define qnames
String targetNamespace = "http://www.openuri.org/";
QName serviceName = new QName(targetNamespace, "org3Test");
QName portName = new QName(targetNamespace, "org3TestSoap");
URL wsdlLocation = new URL("http://localhost:7001/ElecWS/controls/org3Test.jws?WSDL");
// create service
Service service = factory.createService(wsdlLocation, serviceName);
// create Codec
DataGraphCodec dgCodec = new DataGraphCodec(wsdlLocation);
TypeMappingRegistry registry = service.getTypeMappingRegistry();
TypeMapping mapping = registry.getTypeMapping( SOAPConstants.URI_NS_SOAP_ENCODING );
mapping.register( SOAPElement.class,
new QName(targetNamespace, "getCustomer"),
dgCodec,
dgCodec );
mapping.register( SOAPElement.class,
new QName( targetNamespace, "getCustomerResponse" ),
dgCodec,
dgCodec );
mapping.register( SOAPElement.class,
new QName( targetNamespace, "submitArrayOfCustomer" ),
dgCodec,
dgCodec );
mapping.register( SOAPElement.class,
new QName( targetNamespace, "submitArrayOfCustomerResponse" ),
dgCodec,
dgCodec );
// create call for read
Call call = service.createCall(portName, new QName(targetNamespace, "getCustomer"));
XmlObject reqdoc = XmlObject.Factory.parse( "<getCustomer xmlns='http://www.openuri.org/'/>");
DataObject[] customerdocs = (DataObject[]) call.invoke(new Object[]{reqdoc});
// user can modify the DataObject here
DataObject customer = customerdocs[0].getDataObject(0);
customer.setString("EmailAddress", "BEAarray@BEA.com");
String dgstring = customer.getDataGraph().toString();
System.out.println(dgstring);
// create call for submit
call = service.createCall(portName, new QName(targetNamespace, "submitArrayOfCustomer"));
XmlObject submitdoc = XmlObject.Factory.parse( "<sub:submitArrayOfCustomer xmlns:sub='http://www.openuri.org/'><sub:docs>" + dgstring + "</sub:docs></sub:submitArrayOfCustomer>");
Object obj = call.invoke(new Object[]{submitdoc});
System.out.println(obj);
}
}
![]() ![]() ![]() |