Programming WebLogic Web Services
The following sections provide information about using the WebLogic Web Services APIs:
WebLogic Web Services provide APIs, in addition to the JAX-RPC and SAAJ APIs, that you can use for a variety of tasks. These APIs are mostly for use in client applications, although in some cases you can use the APIs in server-side components, such as EJBs.
The sections here discuss the main usage scenarios for WebLogic Web Services APIs; for full reference information about the APIs, see the Javadocs.
The following table lists all the WebLogic Web Services APIs and their main uses.
Used in a client application to invoke an operation asynchronously by splitting the invocation into two methods: the first method invokes the operation with the required parameters but does not wait for the result; later, the second method returns the actual results. |
|
Used in a client application to set verbose mode and the character set programmatically. See Setting Verbose Mode Programatically and Setting the Character Set When Invoking a Web Service. |
|
Used in a client application to configure SSL. See Configuring SSL for a Client Application. |
|
Used to access the |
|
Used in a dynamic client application to register data type mapping information about any non-built-in data types used as a parameter or return value in a Web Service operation invocation. See Registering Data Type Mapping Information in a Dynamic Client. |
|
Used in a client application to introspect the WSDL of the invoked Web Service. |
The stubs in the client JAR file generated by the clientgen
Ant task include the Java code needed by client applications to handle the data type mapping and registration for non-built-in data types used as parameters or return values of Web Service operations. If, however, you are writing a dynamic client to invoke the Web Service, then you must handle the data type mapping registration yourself because dynamic clients do not use the clientgen
-generated stubs.
The standard way to register a data type mapping is to use the JAX-RPC TypeMappingRegistry
class. However, using this class can be cumbersome because you must register the serialization classes manually, and some of these serialization classes might be internal WebLogic classes. The following example shows how to use the TypeMappingRegistry
class, with the relevant code in bold:
package examples.jaxrpc.call3;
import javax.xml.soap.SOAPConstants;
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.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import org.soapinterop.xsd.SOAPStructCodec;
import org.soapinterop.xsd.SOAPStruct;
public class MSInterop{
public static void main( String[] args ) throws Exception{
//set weblogic ServiceFactory
System.setProperty( "javax.xml.rpc.ServiceFactory",
"weblogic.webservice.core.rpc.ServiceFactoryImpl" );
//create service factory
ServiceFactory factory = ServiceFactory.newInstance();
//define qnames
String targetNamespace = "http://soapinterop.org/";
QName serviceName = new QName( targetNamespace, "SimpleTest" );
QName portName = new QName( targetNamespace, "SimpleTestSoap" );
QName operationName = new QName( "http://soapinterop.org/",
"echoStruct" );
//create service
Service service = factory.createService( serviceName );
TypeMappingRegistry registry = service.getTypeMappingRegistry();
TypeMapping mapping = registry.getTypeMapping(
SOAPConstants.URI_NS_SOAP_ENCODING );
mapping.register( SOAPStruct.class,
new QName( "http://soapinterop.org/xsd", "SOAPStruct" ),
new SOAPStructCodec(),
new SOAPStructCodec() );
//create call
Call call = service.createCall();
//set port and operation name
call.setPortTypeName( portName );
call.setOperationName( operationName );
call.addParameter( "inputStruct",
new QName( "http://soapinterop.org/xsd", "SOAPStruct" ),
ParameterMode.IN);
call.setReturnType(
new QName( "http://soapinterop.org/xsd", "SOAPStruct" ) );
//set end point address
call.setTargetEndpointAddress(
"http://www.mssoapinterop.org/asmx/simple.asmx" );
SOAPStruct s = new SOAPStruct();
s.setVarInt(2);
s.setVarString("foo");
s.setVarFloat(123123);
System.out.println(s.toString());
SOAPStruct res = (SOAPStruct) call.invoke(new Object[]{s} );
System.out.println( res );
}
}
The WebLogic Web Services weblogic.webservice.encoding package facilitates the mapping registration of non-built-in data types in a dynamic client. The API defines the following two main classes:
DefaultTypeMapping
: Used to register XML data types and associate them with a corresponding Java data type.GenericTypeMapping
: Used to associate all non-built-in XML data types to the generic Java data type SOAPElement
The following procedure describes how to use the DefaultTypeMapping
class in your dynamic client application:
autotype
Ant task to create the serialization class, Java class, XML Schema, and types.xml
file for the non-built-in data types used in your Web Service. Assume for this example that the types.xml
file is generated in the mydir
directory.For details, see Running the autotype Ant Task.
import weblogic.webservice.encoding.GenericTypeMapping;
import weblogic.webservice.encoding.DefaultTypeMapping;
TypeMappingRegistry registry = service.getTypeMappingRegistry();
DefaultTypeMapping
class to register the types.xml
file generated by the autotype
Ant task, as shown in the following code excerpt:registry.registerDefault(
new DefaultTypeMapping( "mydir/types.xml" ) );
Use the weblogic.webservice.context.WebServiceSession class to access the infrastructure inside WebLogic Server that manages HTTP Sessions. Because WebLogic Web Services are not implemented with servlets, but rather with Java classes and EJBs, the HTTP session information is not directly available, so use the weblogic.webservice.context
package to access it. See the Javadoc for javax.servlet.http.HttpSession for information on using WebServiceSession
.
In your Web Service implementation, get a WebServiceSession
object from a WebServiceContext
object, and then use the standard getAttribute()
and setAttribute()
methods to get and set attributes of the session.
Note: In order for the session functionality to work, the client application must support HTTP cookies.
The following example shows a method of the Java class that implements a Web Service that uses the weblogic.webservice.context
API. The method maintains session state between multiple invokes of the Web Service operation.
import weblogic.webservice.context.WebServiceContext;
import weblogic.webservice.context.ContextNotFoundException;
import weblogic.webservice.context.WebServiceSession;
....
/*
* Shows how to use HTTP Session to maintain session state between
* invokes
*/
public int maintainSessionState(){
try{
WebServiceContext wsContext = WebServiceContext.currentContext();
WebServiceSession session = (WebServiceSession)wsContext.getSession();
Integer count = (Integer)session.getAttribute( "count" );
count = (count==null) ?
new Integer( 0 ) : new Integer( count.intValue() + 1 );
session.setAttribute( "count", count );
return count.intValue();
}catch( ContextNotFoundException e ){
e.printStackTrace();
return -1;
}
}
Use the weblogic.webservice.extensions package in a dynamic client application to introspect the WSDL of the Web Service you are invoking. In particular, the WLCall
interface extends the javax.xml.rpc.Call
interface, adding functionality to:
The following example shows how to use the weblogic.webservice.extensions.WLCall
interface to get more information about the parameters of the operation you are invoking in a client application.
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.rmi.RemoteException;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Call;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import weblogic.webservice.encoding.GenericTypeMapping;
import weblogic.webservice.extensions.WLCall;
public class BrowserClient{
public void invoke() throws RemoteException, InvokeFailedException,
ServiceException, IOException{
String url = "http://localhost:7001/mega/TemperatureService?WSDL";
System.setProperty( "javax.xml.rpc.ServiceFactory",
"weblogic.webservice.core.rpc.ServiceFactoryImpl" );
System.setProperty( "weblogic.webservice.servicenamechecking",
"false" );
ServiceFactory factory = ServiceFactory.newInstance();
QName serviceName = new QName( "http://www.bea.com/mega-service/",
"MegaWebService" );
Service service = factory.createService( new URL( url ), serviceName );
TypeMappingRegistry registry = service.getTypeMappingRegistry();
registry.registerDefault( new GenericTypeMapping() );
System.out.println( "+ Service: " + service.getServiceName() );
for( Iterator it = service.getPorts(); it.hasNext(); ){
QName portName = (QName)it.next();
System.out.println( " + Port: " + portName );
Call[] calls = service.getCalls( portName );
printCalls( calls );
}
}
private void printCalls( Call[] calls ){
for( int i=0; i<calls.length; i++ ){
Call call = calls[i];
System.out.println( " + Operation :" + call.getOperationName() );
printParameters( (WLCall)call );
if( call.getReturnType() != null ){
System.out.println( " + Return Type:" + call.getReturnType() );
}
System.out.println( "" );
}
}
private void printParameters( WLCall call ){
for( Iterator it = call.getParameterNames(); it.hasNext(); ){
String name = (String)it.next();
System.out.println( " + Part :" + name );
System.out.println( " - Java Type :" +
call.getParameterJavaType( name ) );
System.out.println( " - Mode :" +
call.getParameterMode( name ) );
System.out.println( " - XML Type :" +
call.getParameterTypeByName( name ) );
}
}
}