WAS v8.5 > Reference > Developer examples

Example: Creating a web service that uses the JAX-WS Web Services Addressing API to access a generic web service resource instance

Consider an IT organization that has a network of printers that it wants to manage using web services. The organization might represent each printer as a resource that is addressed through an endpoint reference. This example shows how to code such a service using the JAX-WS Web Services Addressing (WS-Addressing) APIs provided by WebSphere Application Server.


Providing a web service interface that returns an endpoint reference to the target service

The IT organization implements a PrinterFactory service that offers a CreatePrinter portType element. This portType element accepts a CreatePrinterRequest message to create a resource that represents a logical printer, and responds with an endpoint reference that is a reference to the resource.

The WSDL definition for such a PrinterFactory service might include the following code:

<wsdl:definitions targetNamespace="http://example.org/printer" ...
                  xmlns:pr=" http://example.org/printer">   <wsdl:types>     ...
    <xsd:schema...>       <xsd:element name="CreatePrinterRequest"/>       <xsd:element name="CreatePrinterResponse" 
                   type="wsa:EndpointReferenceType"/>     </xsd:schema>   </wsdl:types>   <wsdl:message name="CreatePrinterRequest">     <wsdl:part name="CreatePrinterRequest" 
               element="pr:CreatePrinterRequest" />   </wsdl:message>   <wsdl:message name="CreatePrinterResponse">     <wsdl:part name="CreatePrinterResponse" 
               element="pr:CreatePrinterResponse" />   </wsdl:message>   <wsdl:portType name="CreatePrinter">     <wsdl:operation name="createPrinter">       <wsdl:input name="CreatePrinterRequest" 
                  message="pr:CreatePrinterRequest" />       <wsdl:output name="CreatePrinterResponse"
                  message="pr:CreatePrinterResponse" />     </wsdl:operation>   </wsdl:portType> </wsdl:definitions>

The CreatePrinter operation in the previous example returns a wsa:EndpointReference object that represents the newly created Printer resource. The client can use this endpoint reference to send messages to the service instance that represents the printer.


Implement the web service interface

The createPrinter method shown in the following example obtains the identifier for the individual printer resource instance. The operation then creates an endpoint reference to the Printer service, and associates the printer ID with the endpoint reference. Finally, the createPrinter method returns the endpoint reference.

import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;

import javax.xml.namespace.QName;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class MyClass {

  // Create the printer
  ...

  //Define the printer resource ID as a static constant as it is required in later steps     public static final QName PRINTER_SERVICE_QNAME = new QName("example.printer.com", "printer", "..."); 
    public static final QName PRINTER_ENDPOINT_NAME = new QName("example.printer.com", "PrinterService", "...");
    
    public W3CEndpointReference createPrinter(java.lang.Object createPrinterRequest)
    {
     Document document = ...;

     // Create or lookup the stateful resource and derive a resource      // identifier string.
     String resource_identifier = "...";
     
     // Associate this resource identifier with the EndpointReference as  
     // a reference parameter.
     // The choice of name is arbitrary, but should be unique     
     // to the service.
     Element element = document.createElementNS("example.printersample",
             "IBM_WSRF_PRINTERID");
     element.appendChild( document.createTextNode(resource_identifier) );
     ...
     
     // Create an EndpointReference that targets the appropriate WebService URI and port name.
     // Alternatively, the getEndpointReference() method of the MessageContext can be used.
     W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
     builder.serviceName(PRINTER_SERVICE_QNAME);
     builder.endpointName(PRINTER_ENDPOINT_NAME);
     builder.referenceParameter(element);
     
     // The endpoint reference now targets the resource rather than the service.
     return builder.build();
    }}


Extend the target service to match incoming messages to web service resource instances

Because of the web service implementation described previously, the printer resource instance now has a unique identifier embedded in its endpoint reference. This identifier becomes a reference parameter in the SOAP header of subsequent messages that are targeted at the web service, and can be used by the web service to match incoming messages to the appropriate printer.

When a web service receives a message containing WS-Addressing message addressing properties, the WAS processes these properties before the message is dispatched to the application endpoint, and sets them into the message context on the thread. The Printer web service application accesses the reference parameters associated with the target endpoint from the WebServiceContext object, as illustrated in the following example:

@Resource
private WebServiceContext context;
...
List list = (List) context.getMessageContext().get(MessageContext.REFERENCE_PARAMETERS);

If the application uses the 2004/08 version of the WS-Addressing specification, use the IBM proprietary API to retrieve the message parameters, as illustrated in the following example.

import com.ibm.websphere.wsaddressing.EndpointReferenceManager; 
...
 // Initialize the reference parameter name  QName name = new QName(..);
 // Extract the String value.
 String resource_identifier = 
        EndpointReferenceManager.getReferenceParameterFromMessageContext(PRINTER_ID_PARAM_QNAME);

The web service implementation can forward messages based on the printer ID to the appropriate printer instances.


Use endpoint references to send messages to an endpoint

The client uses the endpoint reference returned from the service to create a JAX-WS proxy for the printer, as illustrated in the following example.

javax.xml.ws.Service jaxwsServiceObject= ...;
W3CEndpointReference epr = ...;
...
Printer myPrinterProxy = jaxwsServiceObject.getPort(epr, Printer.class, new AddressingFeature());
The proxy object now represents the new printer resource instance, and can be used by the client to send messages to the printer through the Printer Web service. When the client invokes the service, WAS adds appropriate message addressing properties to the message header, which in this case is a reference parameter contained within the endpoint reference that identifies the target printer resource.

From the perspective of the client, the endpoint reference is opaque. The client cannot interpret the contents of any endpoint reference parameters and should not try to use them in any way. Clients cannot directly create instances of endpoint references because the reference parameters are private to the service provider; clients must obtain endpoint references from the service provider, for example through a provider factory service, and then use them to direct web service operations to the endpoint that is represented by the endpoint reference, as shown.


Related concepts:

Web Services Addressing support
Web Services Resource Framework support
Web Services Addressing APIs


Related


Create stateful web services using the Web Services Resource Framework


+

Search Tips   |   Advanced Search