Oracle® Application Server Web Services Developer's Guide 10g (10.1.3.1.0) Part Number B28974-01 |
|
|
View PDF |
This chapter provides information on developing a Web services client for the J2SE platform. This chapter has the following sections.
The J2SE client, unlike the J2EE client, is responsible for much of the underlying work of looking up the service, and creating and maintaining the instances of classes that access the Web service. Since developers cannot rely on the container, they must create and manage their own services, and ensure the availability of all runtime environments needed to access the Web service.
The following sections describe static stub clients and Dynamic Invocation Interface (DII) clients.
The WebServicesAssembler command genProxy
generates static stubs from a supplied WSDL document. The generated stubs implement the javax.xml.rpc.Stub
interface and a service endpoint interface. Additionally, the generated stubs are specifically bound to the HTTP transport and SOAP protocol. You can instantiate the generated stubs and invoke their methods directly to send requests to the associated Web service.
In addition, WebServicesAssembler generates a client utility class that demonstrates how a client leverages the static stubs to interact with a Web service. The name of the utility client class is <WSDL_port_name
>Client.java
. This class handles all steps necessary for creating a stub instance. You may want to instantiate the utility client and use it to invoke the remote service's operations.
Note: The client utility class file is regenerated every time WebServicesAssembler is executed. It is strongly recommended that you place your own code in a separate file; otherwise, you will lose your changes. |
The JAX-RPC Dynamic Invocation Interface enables you to invoke a remote Web service operation even if the name of the service or the signature of the remote method is unknown prior to runtime.
Support for DII is provided through OC4J's implementation of the javax.xml.rpc.Call
interface. The javax.xml.rpc.Service
class acts as a factory for Call
instances by using the overloaded Service.createCall()
method. Once created, the various getters and setters that the Call
interface provides are used to configure the port type, the operation name, the service endpoint address, and other attributes required for executing the remote method.
See Also: "How to Use Dynamic Invocation Interface to Invoke Web Services" for examples of using DII clients to invoke Web services. |
This section contains the following subsections:
Before you begin, provide the following files and information.
Supply the URI to the WSDL you want to employ to generate the client. This chapter uses the WSDL file described in "Sample WSDL File".
Decide on the destination location for generated artifacts.
Decide on a package name for the client files.
You can use WebServicesAssembler to create a J2SE Web service client using static stubs. To create the static stub, follow these steps.
Provide the URI to the WSDL, the name of the output directory, the package name, and the other information and files described in the Prerequisites section as input to the WebServicesAssembler genProxy
command. The following command generates the client proxies and stores them in build/src/client
. The client application uses the stub to invoke operations on a remote service:
Command line:
java -jar wsa.jar -genProxy -output build/src/client/ -wsdl http://localhost:8888/hello/HelloService?WSDL -packageName oracle.demo.hello
Ant task:
<oracle:genProxy wsdl="http://localhost:8888/hello/HelloService?WSDL" output="build/src/client" packageName="oracle.demo.hello"/>
In this command and Ant task:
genProxy
—Creates a static proxy stub that can be used by a J2SE Web service client. See "genProxy".
wsdl
—Specifies the absolute file path, relative file path, or URL to a WSDL document. See "wsdl".
output
—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created. See "output".
packageName
—Specifies the package name that will be used for generated classes if no package name is declared in the JAX-RPC mapping file. See "packageName".
For more information on the required and optional arguments to genProxy
, see "genProxy".
Use the client utility class file created by genProxy
as your application client, or use it as a template to write your own client code. The client utility class file is one of a number of files created by genProxy
.
You can also use the client utility class file to test your endpoint. Example 15-2, "HelloInterfacePortClient.java Listing", illustrates the client utility class file created in this example. For more information about this file, see "Writing Web Service Client Applications".
Compile the client files and put them in the classpath.
List the appropriate JARs on the classpath before compiling the client. Table A-2, "Classpath Components for a Client Using a Client-Side Proxy" lists all of the JAR files that can possibly be used on the client classpath. As an alternative to listing individual JARs, you can include the client-side JAR, wsclient_extended.jar
on the client classpath. This JAR file contains all the classes necessary to compile and run a Web service client. The classes are from the individual JAR files listed in Table A-2. See "Setting the Classpath for a Web Service Proxy" for more information on wsclient_extended.jar
and the client classpath.
Run the J2SE client from the command line.
Example 15-1 contains a partial listing of the HelloService.wsdl
used to generate the client. One of the files generated from this WSDL is the client utility class file listed in Example 15-2.
This partial listing illustrates a number of entries in the WSDL file that are employed in the generation of the client utility class file. For example:
The name of the client utility class file, HelloInterfacePortClient.java
, is derived from the value of the <port name>
attribute.
The operation name, sayHello
, which appears under the <portType>
element, becomes a method in the client utility class file.
The parameter and data type belonging to sayHello
is defined by the complexType
defining the sayHello
request:
<complexType name="sayHello"> <sequence> <element name="name" nillable="true" type="string"/> </sequence> </complexType>
The preceding elements appear in bold in the partial listing of HelloService.wsdl
.
Example 15-1 WSDL Fragment, With Elements Used in the Client Utility Class File
<definitions ... > <types> <schema targetNamespace="http://hello.demo.oracle/" ... xmlns="http://www.w3.org/2001/XMLSchema" ... <complexType name="sayHello"> <sequence> <element name="name" nillable="true" type="string"/> </sequence> </complexType> <complexType name="sayHelloResponse"> <sequence> <element name="result" nillable="true" type="string"/> </sequence> </complexType> <element name="sayHelloElement" type="tns:sayHello"/> <element name="sayHelloResponseElement" type="tns:sayHelloResponse"/> </schema> </types> <message name="HelloInterface_sayHelloResponse"> <part name="parameters" element="tns:sayHelloResponseElement"/> </message> <message name="HelloInterface_sayHello"> <part name="parameters" element="tns:sayHelloElement"/> </message> <portType name="HelloInterface"> <operation name="sayHello"> <input message="tns:HelloInterface_sayHello"/> <output message="tns:HelloInterface_sayHelloResponse"/> </operation> </portType> <binding name="HelloInterfacePortBinding" type="tns:HelloInterface"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayHello"> <soap:operation soapAction="http://hello.demo.oracle/:sayHello"/> <input> <soap:body use="literal" parts="parameters"/> </input> <output> <soap:body use="literal" parts="parameters"/> </output> </operation> </binding> <service name="HelloService"> <port name="HelloInterfacePort" binding="tns:HelloInterfacePortBinding"> <soap:address location="HelloService"/> </port> </service> </definitions>
This section contains the following subsections:
The genProxy
command generates a client utility class file that enables you to invoke Web service methods. You can use this file as your application client, or use it as a template to write your own application client code.
Note: The client utility class file is regenerated each time you rungenProxy . If you add code to this file for testing purposes, then your changes will be lost if you regenerate the proxy. For production code, your client code should exist outside of this utility class. |
The command derives the name of the file by appending the suffix Client
to the port name. For example, for the HelloInterfacePort
port name, genProxy
generates the HelloInterfacePortClient.java
file.
See Also: Example 15-2, "HelloInterfacePortClient.java Listing" for an example of a client utility class file generated by the |
The client utility class serves as a proxy to the Web service implementation. The client-side proxy code constructs a SOAP request and marshals and unmarshals parameters for you. Using the proxy classes saves you the work of creating SOAP requests and data marshalling for accessing a Web service or processing Web service responses.
The most important part of the client utility class file is the factory code for creating javax.xml.rpc.Service
objects and obtaining the operations available on the service. The Service
object acts as an instance of the generated stub class.
Note the following lines of code in the client utility class file:
public HelloInterfaceClient() throws Exception { ServiceFactory factory = ServiceFactory.newInstance(); _port = ((HelloService)factory.loadService (HelloService.class)).getHelloInterfacePort(); }
If you write your own application client, then you must supply this code to create the service factory and obtain a port implementation.
The following steps describe the code.
Instantiate a new javax.xml.rpc.ServiceFactory
instance or use an existing instance.
ServiceFactory factory = ServiceFactory.newInstance();
Load the service for a particular service endpoint interface using the loadService
method. This returns an object of type Service
that also implements the requested service endpoint interface.
(HelloService)factory.loadService(HelloService.class)
In this example, the returned Service
is cast to the service endpoint interface HelloService
.
Use the get
...()
method to get the desired port. The ellipsis ("...") represents the value of the port name
element in the WSDL.
HelloService.getHelloInterfacePort();
In this example, the method name is getHelloInterfacePort()
, where HelloInterfacePort
is the port name
in the WSDL. The method returns a Java implementation for HelloInterfacePort
.
Example 15-2 displays the client utility class file, HelloInterfacePortClient.java
, which was generated from the HelloService.wsdl
in Example 15-1 by the genProxy
command.
The lines of code that create the Service
objects and obtain the operations available on the service appear in bold. Note the generated code that can be used to set the SESSION_MAINTAIN_PROPERTY
system property to alert the client that the Web service is stateful. The session will be maintained when the client is operating in conjunction with a server side, stateful Web service. By maintaining the session, subsequent requests to the service are faster.
Example 15-2 HelloInterfacePortClient.java Listing
import oracle.webservices.transport.ClientTransport; import oracle.webservices.OracleStub; import javax.xml.rpc.ServiceFactory; import javax.xml.rpc.Stub; public class HelloInterfacePortClient { private HelloInterface _port; public HelloInterfacePortClient() throws Exception { ServiceFactory factory = ServiceFactory.newInstance(); _port =((HelloService)factory.loadService( HelloService.class)).getHelloInterfacePort(); } /** * @param args */ public static void main(String[] args) { try { HelloInterfacePortClient myPort = new HelloInterfacePortClient(); System.out.println("calling " + myPort.getEndpoint()); // Add your own code here } catch (Exception ex) { ex.printStackTrace(); } } /** * delegate all operations to the underlying implementation class. */ // sayHello public String sayHello(String name) throws java.rmi.RemoteException { return _port.sayHello(name); } /** * used to access the JAX-RPC level APIs * returns the interface of the port instance */ public oracle.demo.hello.HelloInterface getPort() { return _port; } public String getEndpoint() { return (String) ((Stub) _port)._getProperty(Stub.ENDPOINT_ADDRESS_PROPERTY); } public void setEndpoint(String endpoint) { ((Stub) _port)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endpoint); } public String getPassword() { return (String) ((Stub) _port)._getProperty(Stub.PASSWORD_PROPERTY); } public void setPassword(String password) { ((Stub) _port)._setProperty(Stub.PASSWORD_PROPERTY, password); } public String getUsername() { return (String) ((Stub) _port)._getProperty(Stub.USERNAME_PROPERTY); } public void setUsername(String username) { ((Stub) _port)._setProperty(Stub.USERNAME_PROPERTY, username); } public void setMaintainSession(boolean maintainSession) { ((Stub) _port)._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, new Boolean(maintainSession)); } public boolean getMaintainSession() { return ((Boolean) ((Stub) _port)._getProperty(Stub.SESSION_MAINTAIN_PROPERTY)).booleanValue(); } /** * returns the transport context */ public ClientTransport getClientTransport() { return ((OracleStub) _port).getClientTransport(); } }
OracleAS Web Services permits the chunked transfer encoding of messages when the protocol is HTTP 1.1. Chunked data transfer can be invoked on J2SE stub, J2EE stub and DII Web service clients.
See Also: "How to Enable Chunked Data Transfer for HTTP 1.1" for more information on how to enable this feature. |
By default, a client assembled under Oracle Application Server Web Services sends a request message with a SOAP envelope encoded with UTF-8 characters. To override this behavior, you can set the following Oracle proprietary property:
oracle.webservices.ClientConstants.CHARACTER_SET_ENCODING
Use this property to set the character encoding for a J2SE client or a J2EE client.
See Also: "How to Set a Character Encoding for a SOAP Message" for more information on how to use the |
A client stub can be used to set the cookies used in an HTTP request. The Cookie
class represents an HTTP cookie and can be found in the Oracle Applications Server 10g HTTPClient
package. Cookie
has the following constructor:
Cookie (java.lang.String
name
, java.lang.String
value
, java.lang.String
domain
,
java.lang.String
path
, java.util.Date
expires
, boolean
secure
)
All parameters except expires
are required to the Cookie
constructor.
The domain that you specify for the cookie must be either:
the full host name, or
in the case where the cookie is shared between multiple hosts, the domain must start with a period. For example:
.oracle.com
The following general steps describe how to set a cookie in an HTTP request:
Create a java.util.Map
object to contain the cookies.
Construct one or more cookies, using the Cookie
class from the Oracle Applications Server 10g HTTPClient
package.
Load the cookies into the Map
object.
Set the property oracle.webservices.ClientConstants.COOKIE_MAP
.
The value of the property is a java.util.Map
object that contains items and keys of type HTTPClient.Cookie
.
Set the javax.xml.rpc.session.SESSION_MAINTAIN_PROPERTY
runtime property set to true
.
This property alerts the client that the Web service is stateful. If this property is not set to true
, then the cookies will be ignored.
Example 15-3 illustrates stub code that sets the value of two cookies. The cookieMap
variable is declared to be of type java.util.Map
and obtains its contents from a HashMap
. The Cookie
constructor is used to define two cookies, cookie
and cookie2
. The cookieMap.put
lines add the cookies to the hashmap. The Stub.SESSION_MAINTAIN_PROPERTY
is present and set to true
and the ClientConstants.COOKIE_MAP
is set to cookieMap
.
Example 15-3 Setting a Cookie in a Client Stub
import HTTPClient.Cookie; Map cookieMap = new HashMap(); Cookie cookie = new Cookie("name", "value", ".oracle.com", "/", null, false); Cookie cookie2 = new Cookie("name2", "value2", ".oracle.com", "/", null, false); cookieMap.put(cookie, cookie); cookieMap.put(cookie2, cookie2); ((Stub) port)._setProperty(ClientConstants.COOKIE_MAP, cookieMap); ((Stub) port)._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE); ...
Invoking a Web service by using the Dynamic Invocation Interface (DII) requires a number of steps. At each step, you typically have to make some choices. The examples at the end of this section display choices made at each of the steps.
Using DII to invoke a Web Service consists of the following general steps:
Create the call object.
Register parameters.
Invoke the Web service.
You can create the call object either with or without a WSDL. If you do not have a WSDL, or decide not to use the WSDL for creating the call dynamically, then follow the steps under "Basic Calls". If you do have a WSDL to construct the call, then follow the instructions under "Configured Calls".
For a basic call, the call object is created dynamically without a WSDL. The following steps provide more information on how to construct a basic call.
You are constructing a call object dynamically, without a WSDL. For examples, see:
Register parameters.
Case 1: You are constructing the SOAP request yourself as a SOAPElement
, and are receiving the response as a SOAPElement
. In this case, you do not have to register parameters or return types. For examples of this case, see:
Case 2: You are explicitly registering the parameters and returns (parts) that are being used in the Web service invocation in your Basic Call, including the part name, the XML and Java type names, and the parameter mode. In this case, you can furnish the individual parameters as Java object instances. For an example of this case, see:
Invoke the Web service. You can invoke the Web service either by using SOAPElement
or by Java bindings.
Case 1: Using SOAPElement
. If you are using a document-literal invocation, then you will typically construct a SOAPElement
for your message and pass it to the invoke()
method. Note that this invocation employs the public, Oracle specific API from OracleCall
. For examples of this case, see:
Case 2: Using Java bindings. If you are using an RPC-literal or RPC-encoded invocation, then you will typically supply an array containing Java objects in the invoke()
method and cast the return object to the anticipated return type. For examples of this case, see:
For a configured call, the call object is constructed from a WSDL. The following steps provide more information on how to construct a configured call.
Provide the WSDL for constructing the call object. For examples, see:
Register parameters. For a Configured Call, you must register parameters for the following cases:
Case 1: You are employing a complex or other type that is not being mapped to a primitive Java type (or an Object variant of a primitive Java type). For examples of this case, see:
Case 2: You are using a document-literal wrapped style and do not want to create a SOAPElement
like the ones illustrated in Example 15-7 and Example 15-9 for Basic Call. In this case, the name of the parameter must be the QName
of the wrapper. For an example of this case, see:
Case 3: If Case 1 and Case 2 do not apply, then you do not have to register parameters or returns. For an example of this case, see:
Invoke the Web service. You can invoke the Web service either by using SOAPElement
or by Java bindings.
Case 1: Using SOAPElement
. If you are using a document-literal invocation, then you will typically construct a SOAPElement
for your message and pass it to the invoke()
method. Note that this invocation employs the public, Oracle specific API from OracleCall
. For examples of this case, see:
Case 2: Using Java bindings. If you are using an RPC-literal or RPC-encoded invocation, then you will typically supply an array containing Java objects in the invoke()
method and cast the return object to the anticipated return type. For examples of this case, see:
This section provides a variety of client examples that use basic calls or configured calls to invoke a Web service.
The following code snippet illustrates an import
statement that can be used by the following code examples.
import javax.xml.rpc.ServiceFactory; import javax.xml.rpc.Service; import javax.xml.rpc.Call; import javax.xml.rpc.ParameterMode; import javax.xml.namespace.QName; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPElement; import java.net.URL; import oracle.webservices.OracleCall; import oracle.xml.parser.v2.XMLElement;
Example 15-4 Basic Call with parameter registration and Java bindings
// (1) Creation of call object without WSDL. String endpoint = "http://localhost:8888/echo/DiiDocEchoService"; ServiceFactory sf = ServiceFactory.newInstance(); Service service = sf.createService(new QName("http://echo.demo.oracle/", "tns")); Call call = service.createCall(); // (2) Configuration of call and registration of parameters. call.setTargetEndpointAddress(endpoint); call.setProperty(Call.SOAPACTION_USE_PROPERTY, new Boolean(true)); call.setProperty(Call.SOAPACTION_URI_PROPERTY, ""); call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY, "http://schemas.xmlsoap.org/soap/encoding/"); call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc"); QName QNAME_TYPE_STRING = new QName("http://www.w3.org/2001/XMLSchema", "string"); call.addParameter("s", QNAME_TYPE_STRING, ParameterMode.IN); call.setReturnType(QNAME_TYPE_STRING); // (3) Invocation. System.out.println("Response is " + call.invoke(new Object[]{"hello"}));
Example 15-5 Configured Call with Java bindings, but without parameter registration
/// (1) Creation of call object using WSDL. String namespace = "http://www.xmethods.net/sd/CurrencyExchangeService.wsdl"; URL wsdl=new URL(namespace); ServiceFactory factory = ServiceFactory.newInstance(); QName serviceName = new QName(namespace, "CurrencyExchangeService"); Service service = factory.createService(wsdl, serviceName); QName portName = new QName(namespace, "CurrencyExchangePort"); Call call = service.createCall(portName); // (2) Registration of parameters. // -> taken from the WSDL // (3) Configuration of operation and invocation. QName operationName = new QName("urn:xmethods-CurrencyExchange", "getRate"); call.setOperationName(operationName); Float rate = (Float) call.invoke(new Object[]{"usa", "canada"}); System.out.println("getRate: " + rate);
Example 15-6 Configured Call with registration of wrapper parameters and Java bindings
// (1) Creation of call object using WSDL. String namespace = "http://server.hello/jaxws"; ServiceFactory factory = ServiceFactory.newInstance(); QName serviceName = new QName(namespace, "HelloImplService"); URL wsdl=new URL(namespace+"?WSDL"); Service service = factory.createService(wsdl, serviceName); QName portName = new QName(namespace, "HelloImpl"); Call call = service.createCall(portName); // (2) Registration of SayHello and SayHelloResponse wrapper classes // These must be available in the classpath. String TYPE_NAMESPACE_VALUE = "http://server.hello/jaxws"; QName reqQname = new QName(TYPE_NAMESPACE_VALUE,"sayHelloElement"); QName respQName = new QName(TYPE_NAMESPACE_VALUE,"sayHelloResponseElement"); call.addParameter("name", reqQname, SayHello.class, ParameterMode.IN ); call.setReturnType(respQName, SayHelloResponse.class ); // (3) Invocation SayHello input = new SayHello("Duke"); Object[] params = new Object[] { input }; SayHelloResponse result = (SayHelloResponse) call.invoke( params ); String response = result.getResult();
Example 15-7 Basic Call with SOAPElement, but without parameter registration
// (1) Creation of call object without WSDL ServiceFactory sf = ServiceFactory.newInstance(); Service service = sf.createService(new QName("http://echo.demo.oracle/", "tns")); Call call = service.createCall(); call.setTargetEndpointAddress("http://localhost:8888/echo/DiiDocEchoService"); // (2) No registration of parameters // (3a) Direct creation of payload as SOAPElement SOAPFactory soapfactory = SOAPFactory.newInstance(); SOAPElement m1 = soapfactory.createElement("echoStringElement", "tns", "http://echo.demo.oracle/"); SOAPElement m2 = soapfactory.createElement("s", "tns", "http://echo.demo.oracle/"); m2.addTextNode("Bob"); m1.addChildElement(m2); System.out.println("Request is: "); ((XMLElement) m1).print(System.out); // (3b) Invocation SOAPElement resp = (SOAPElement) ((OracleCall) call).invoke(m1); System.out.println("Response is: "); ((XMLElement) resp).print(System.out);
Example 15-8 Configured Call with a WSDL, complex return parameter registration, and Java bindings
// (0) Preparing a complex argument value Integer req_I = new Integer( Integer.MAX_VALUE ); String req_s = "testDocLitBindingAnonymAll & <body>"; Integer req_inner_I = new Integer( Integer.MIN_VALUE ); String req_inner_s = "<inner> & <body>"; int[] req_inner_i = {0,Integer.MAX_VALUE, Integer.MIN_VALUE}; InnerSequence req_inner = new InnerSequence(); req_inner.setVarInteger( req_inner_I ); req_inner.setVarString ( req_inner_s ); req_inner.setVarInt ( req_inner_i ); EchoAnonymAllElement req = new EchoAnonymAllElement(); req.setVarInteger ( req_I ); req.setVarString ( req_s ); req.setInnerSequence( req_inner); // (1) Creation of call object using the WSDL String TARGET_NS = "http://soapinterop.org/DocLitBinding"; String TYPE_NS = "http://soapinterop.org/xsd"; String XSD_NS = "http://www.w3.org/2001/XMLSchema"; QName SERVICE_NAME = new QName( TARGET_NS, "DocLitBindingService" ); QName PORT_NAME = new QName( TARGET_NS, "DocLitBindingPort"); String wsdlUrl = "http://"+getProperty("HOST")+ ":"+getProperty("HTTP_PORT")+ "/doclit_binding/doclit_binding"; QName operation = new QName(TARGET_NS, "echoAnonymAll"); ServiceFactory factory = ServiceFactory.newInstance(); Service srv = factory.createService( new URL(wsdlUrl + "?WSDL"), SERVICE_NAME); Call call = srv.createCall( PORT_NAME, operation ); // (2) Registration of complex return parameter call.setReturnType(new QName(TYPE_NS, "EchoAnonymAllElement"), EchoAnonymAllElement.class); // (3) Invocation EchoAnonymAllElement res = (EchoAnonymAllElement) call.invoke( new Object[]{req} ); System.out.println( "AnonymAll body : " +res.getVarString() ); System.out.println( "AnonymAll inner : " +res.getInnerSequence() );
Example 15-9 Basic Call with document-literal invocation and SOAPElement, but without parameter registration
// (1) Creation of Basic Call ServiceFactory sf = ServiceFactory.newInstance(); Service service = sf.createService(new QName("http://echo.demo.oracle/", "tns")); String endpoint="http://localhost:8888/test/echo"; Call call = service.createCall(); call.setTargetEndpointAddress(endpoint); // (2) No parameter registration // (3) Invocation using SOAPElement SOAPFactory soapfactory = SOAPFactory.newInstance(); SOAPElement m1 = soapfactory.createElement("echoStringElement", "tns", "http://echo.demo.oracle/"); SOAPElement m2 = soapfactory.createElement("s", "tns", "http://echo.demo.oracle/"); m2.addTextNode("Bob"); m1.addChildElement(m2); System.out.println("Request is: "); ((XMLElement) m1).print(System.out); SOAPElement resp = (SOAPElement) ((OracleCall) call).invoke(m1); System.out.println("Response is: "); ((XMLElement) resp).print(System.out);
Example 15-10 Configured Call with RPC-encoded invocation, complex parameter registration, and Java bindings
// (1) Creation of ConfiguredCall using WSDL ServiceFactory sf = ServiceFactory.newInstance(); String endpoint="http://localhost:8888/test/echo"; Service service = sf.createService(new java.net.URL(endpoint + "?WSDL"), new QName("http://echo.demo.oracle/", "DiiRpcEchoService")); Call call = service.createCall(new QName("http://echo.demo.oracle/", "HttpSoap11"), new QName("http://echo.demo.oracle/", "echoStrings")); call.setProperty(Call.SOAPACTION_USE_PROPERTY, new Boolean(true)); call.setProperty(Call.SOAPACTION_URI_PROPERTY, ""); call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY, "http://schemas.xmlsoap.org/soap/encoding/"); call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc"); // (2) Registration of complex input and return arguments QName stringArray = new QName("http://echo.demo.oracle/", "stringArray"); call.addParameter("s", stringArray, String[].class, ParameterMode.IN); call.setReturnType(stringArray, String[].class); // (3) Invocation String[] request = new String[]{"bugs", "little_pieces", "candy"}; String[] resp = (String[]) call.invoke(new Object[]{request}); System.out.println("Response is: "); for (int i = 0; i < resp.length; i++) { System.out.print(resp[i] + " "); } System.out.println();
Oracle JDeveloper enables you to build client applications that use Web services. It supports OC4J J2SE Web service clients by allowing you to create Java stubs from Web service WSDL descriptions. You can use these stubs to access existing Web services. For more information, see the Oracle JDeveloper on-line help.
For more information on:
assembling Web services from a WSDL, see Chapter 6, "Assembling a Web Service from WSDL".
assembling stateful Web services, see Chapter 7, "Assembling a Web Service with Java Classes".
assembling Web services from EJBs, see Chapter 8, "Assembling a Web Service with EJBs".
assembling Web services from a JMS queue or topic, see Chapter 9, "Assembling Web Services with JMS Destinations".
assembling Web services from database resources, see Chapter 10, "Assembling Database Web Services".
assembling Web services with J2SE 5.0 Annotations, see Chapter 11, "Assembling Web Services with Annotations".
building J2EE clients, see Chapter 14, "Assembling a J2EE Web Service Client".
improving performance by data chunking, see "How to Enable Chunked Data Transfer for HTTP 1.1".
using the WebServicesAssembler tool to assemble Web services, see Chapter 18, "Using WebServicesAssembler".
packaging and deploying Web services, see Chapter 19, "Packaging and Deploying Web Services".
JAR files that are needed to assemble a client, see Appendix A, "Web Service Client APIs and JARs".
Web services interoperability, see "Ensuring interoperable Web Services" in the Oracle Application Server Advanced Web Services Developer's Guide.
using quality of service features in Web service clients, see "Managing Web Services" in the Oracle Application Server Advanced Web Services Developer's Guide.
adding security to a Web service, see the Oracle Application Server Web Services Security Guide.
how to write clients to access Web services secured on the transport level, see "Adding Transport-level Security for Web Services Based on EJBs" and "Accessing Web Services Secured on the Transport Level" in the Oracle Application Server Web Services Security Guide.
adding reliability to a Web service, see "Ensuring Web Service Reliability" in the Oracle Application Server Advanced Web Services Developer's Guide.
adding an auditing and logging configuration to a Web service, see "Auditing and Logging Messages" in the Oracle Application Server Advanced Web Services Developer's Guide.
processing nonstandard data types, see "Custom Serialization of Java Value Types" in the Oracle Application Server Advanced Web Services Developer's Guide.
the JAX-RPC mapping file, see "JAX-RPC Mapping File Descriptor" in the Oracle Application Server Advanced Web Services Developer's Guide.
data types supported by OracleAS Web Services, see "Mapping Java Types to XML and WSDL Types" in the Oracle Application Server Advanced Web Services Developer's Guide.
Oracle JDeveloper tool support for Web service development, see the Oracle JDeveloper on-line help.