Exemple : Création d'un service Web qui utilise l'API JAX-WS Web Services Addressing pour accéder à une instance de ressource de service Web générique
Supposons par exemple qu'une entreprise de technologies de l'information souhaite gérer son réseau d'imprimantes à l'aide de services Web. Cette entreprise peut représenter chaque imprimante sous forme de ressource dont l'adressage est effectué via une référence de noeud final (EndpointReference). Cet exemple montre comment coder ce type de service à l'aide des API (interfaces de programmation d'application) JAX-WS Web Services Addressing (WS-Addressing) fournies par WebSphere Application Server.
Création d'une interface de service Web qui renvoie une référence de noeud final au service cible
L'entreprise TI implémente un service PrinterFactory qui fournit un élément portType CreatePrinter. Cet élément portType accepte un message CreatePrinterRequest pour créer une ressource qui représente une imprimante logique et répond par une référence de noeud final qui est une référence à la ressource.
<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>
L'opération CreatePrinter dans l'exemple précédent renvoie un objet wsa:EndpointReference qui représente la ressource Printer créée. Le client peut utiliser cette référence de noeud final pour envoyer des messages à l'instance de service qui représente l'imprimante.
Implémentation de l'interface du service Web
La méthode createPrinter illustrée dans l'exemple ci-dessous permet d'obtenir l'identificateur de l'instance de ressource de l'imprimante en question. Au cours de cette opération, le programme crée ensuite une référence de noeud final vers le service d'imprimante et associe l'ID imprimante à la référence de noeud final. Enfin, la méthode createPrinter renvoie la référence de noeud final.
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();
}
}
Extension du service cible pour faire correspondre les messages entrants aux instances de ressource de service Web
Grâce à l'implémentation du service Web décrite précédemment, l'instance de ressource de l'imprimante est maintenant associée à un identificateur unique imbriqué à la référence de noeud final. Cet identificateur devient un paramètre de référence dans l'en-tête SOAP des messages suivants ciblés sur le service Web, et peut être utilisé par le service Web pour faire correspondre les messages entrants à l'imprimante appropriée.
Lorsqu'un service Web reçoit un message contenant des propriétés d'adressage de message WS-Addressing, WebSphere Application Server traite ces propriétés avant l'envoi du message au noeud final de l'application et les définit dans le contexte du message sur l'unité d'exécution. L'application de service Web d'imprimante accède aux paramètres de référence associés au noeud final cible de l'objet WebServiceContext, comme le montre l'exemple suivant :
@Resource
private WebServiceContext context;
...
List list = (List) context.getMessageContext().get(MessageContext.REFERENCE_PARAMETERS);
Si votre application utilise la version 2004/08 de la spécification WS-Addressing, utilisez l'API propriété d'IBM pour récupérer les paramètres de message, comme le montre l'exemple suivant.
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);
L'implémentation du service Web peut transférer les messages à partir de l'ID imprimante vers les instances d'imprimante appropriées.
Utilisation de références de noeud final pour envoyer des messages à un noeud final
javax.xml.ws.Service jaxwsServiceObject= ...;
W3CEndpointReference epr = ...;
...
Printer myPrinterProxy = jaxwsServiceObject.getPort(epr, Printer.class, new AddressingFeature());
L'objet proxy représente désormais la nouvelle instance de
ressource d'imprimante et permet au client de envoyer des messages
à l'imprimante via le service Web correspondant. Lorsque le client appelle le service, WebSphere Application Server ajoute à l'en-tête du message les propriétés d'adressage de message appropriées. Dans l'exemple il s'agit d'un paramètre de référence inclus dans la référence de noeud final qui identifie la ressource d'imprimante cible.Du point de vue du client, la référence de noeud final est opaque. Le client ne peut pas interpréter le contenu des paramètres de référence de noeud final et il ne doit pas tenter de les utiliser d'une autre manière. Les clients ne peuvent pas créer directement des instances de références de noeud final, car les paramètres des références sont privés pour le fournisseur de services et les clients doivent obtenir les références de noeud final auprès de celui-ci, par exemple via un service de fabrique de fournisseur, puis les utiliser pour diriger les opérations du service Web vers le noeud final représenté par la référence de noeud final, comme illustré ici.