Appels de services Web JAX-WS de manière asynchrone
Java™ API for XML-Based Web services(JAX-WS)fournit un support pour l'appel de services web via un appel client asynchrone. JAX-WS fournit le support pour un modèle d'appel et d'interrogation lors de l'appel asynchrone de services web. Les modèles d'interrogation et d'appel sont disponibles sur le client Dispatch et le client Dynamic Proxy.
Avant de commencer
Développement d'un client Dynamic Proxy ou Dispatch JAX-WS. Lors du développement de clients Dynamic Proxy, après la génération des artefacts de client portables à partir d'un fichier WSDL utilisant la commande wsimport, l'interface SEI générée n'a pas de méthode asynchrone incluse dans l'interface. Utilisez les liaisons JAX-WS pour ajouter les méthodes d'appel ou d'interrogation asynchrones sur l'interface pour le client Dynamic Proxy. Pour activer les mappages asynchrones, vous pouvez ajouter la déclaration de liaison jaxws:enableAsyncMapping au fichier WSDL. Pour plus d'informations sur l'ajout de personnalisations de liaison afin de générer une interface asynchrone, consultez le chapitre 8 de la spécification JAX-WS.

Pourquoi et quand exécuter cette tâche
Un appel asynchrone d'un service web envoie une demande au noeud final de service puis renvoie immédiatement le contrôle au programme client sans attendre le retour de la réponse provenant du service. Les clients de service web asynchrones JAX-WS utilisent des services Web à l'aide de l'approche d'appel ou d'interrogation. A l'aide d'un modèle d'interrogation, un client peut émettre une demande et recevoir un objet de réponse qui est interrogé pour déterminer si le serveur a répondu. Lorsque le serveur répond, la réponse réelle est extraite. Le modèle de rappel permet au client de fournir un gestionnaire d'appel pour accepter et traiter l'objet réponse entrante. La méthode handleResponse() du gestionnaire est appelée lorsque le résultat est disponible. Les modèles d'appel et d'interrogation permettent au client de continuer à effectuer le traitement sans attendre le retour d'une réponse, tout en fournissant un modèle plus dynamique et plus efficace pour appeler les services web. Les appels d'interrogation issus de clients EJB (Enterprise JavaBeans) ou de clients d'application Java EE (Java Platform, Enterprise Edition) sont valides. Les invocations d'appels ne sont valides qu'à partir de clients d'application Java EE.
- Utilisation du modèle d'appel asynchrone de rappel
- Pour implémenter un appel asycnhrone qui utilise le modèle d'appel, le client fournit un gestionnaire de rappels AsyncHandler pour accepter et traiter l'objet de réponse entrant. Le gestionnaire d'appel client implémente l'interface javax.xml.ws.AsyncHandler qui contient le code d'application exécuté lorsqu'une réponse asynchrone est reçue du serveur. L'interface javax.xml.ws.AsyncHandler contient la méthode handleResponse(java.xml.ws.Response) qui est appelée une fois que l'environnement d'exécution a reçu et traité la réponse asynchrone du serveur. La réponse est transmise au gestionnaire de rappels sous la forme d'un objet javax.xml.ws.Response. L'objet de réponse renvoie le contenu de réponse lorsque la méthode get() est appelée. De plus, si une erreur a été reçue, une exception est renvoyée au client lors de cet appel. La méthode response est ensuite appelée selon le modèle d'unités d'exécution utilisé par la méthode executor, java.util.concurrent.Executor sur l'instance java.xml.ws.Service du client utilisée pour la création de l'instance client Dynamic Proxy ou Dispatch. Le programme d'exécution permet d'appeler des rappels asynchrones enregistrés par l'application. Utilisez les méthodes setExecutor et getExecutor pour modifier et extraire le programme d'exécution configuré pour votre service.
- Utilisation du modèle d'appel asynchrone d'interrogation
- A l'aide du modèle d'interrogation, un client peut émettre une demande et recevoir un objet de réponse pouvant ensuite être interrogé pour déterminer si le serveur a répondu. Lorsque le serveur répond, la réponse réelle peut être extraite. L'objet de réponse renvoie le contenu de réponse lorsque la méthode get() est appelée. Le client reçoit un objet de type javax.xml.ws.Response à partir de la méthode invokeAsync. Cet objet Response permet de surveiller le statut de la demande au serveur, de déterminer le moment où l'opération est terminée et d'extraire les résultats de la réponse.
- Utilisation d'un échange de message asynchrone
- Par défaut, les appels de client asynchrone n'ont pas le comportement asynchrone du modèle d'échange de message sur le réseau. Le modèle de programmation est asynchrone. Toutefois, l'échange des messages de demande et de réponse avec le serveur n'est pas asynchrone. Pour utiliser un échange de messages asynchrone, la propriété com.ibm.websphere.webservices.use.async.mep doit être définie dans le contexte de demande client avec une valeur booléenne, true. Lorsque cette propriété est activée, les messages échangés entre le client et le serveur sont différents des messages échangés de manière synchrone. Avec un échange asynchrone, les messages de demande et de réponse ont des en-têtes WS-Addressing qui fournissent des informations d'acheminement supplémentaires pour les messages. Une autre différence principale entre l'échange de message synchrone et asynchrone réside dans le fait que la réponse est transmise à un port d'écoute asynchrone qui transmet ensuite cette réponse au client. Pour les échanges asynchrones, il n'existe aucun délai d'attente qui est envoyé pour indiquer au client d'arrêter l'écoute d'une réponse. Pour provoquer l'arrêt de l'attente d'une réponse par le client, émettez une méthode Response.cancel() sur l'objet renvoyé d'un appel d'interrogation ou une méthode Future.cancel() sur l'objet renvoyé d'un appel de rappel. L'annulation n'a aucune conséquence sur le serveur lors du traitement d'une demande.

<soapenv:Header>
<wsa:To>http://target.bar.com:81/LiteSecurityService/SecurityService</wsa:To>
<wsa:ReplyTo>
<wsa:Address>http://myhost:2146/axis2/services/LiteSecurityService.
WSRMServicePort/AnonOutInOp?IBMwebservicesID=922A5DC38A337C4CEF1168347862705
</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>urn:uuid:922A5DC38A337C4CEF1168347862403</wsa:MessageID>
<wsa:Action>getEndpointReference</wsa:Action>
</soapenv:Header>
Pour résoudre ce problème, configurez le client à envoyer les détails de l'emplacement de l'écouteur asynchrone au format IP, en ajoutant la propriété système suivante à la machine virtuelle Java. Notez qu'en transmettant l'adresse IP, vous perdez les avantages du protocole DHCP. -Dcom.ibm.websphere.webservices.transportEPRInIPAddr=yes
gotchaProcédure
Résultats
Exemple
@WebService
public interface CreditRatingService {
// Synchronous operation.
Score getCreditScore(Customer customer);
// Asynchronous operation with polling.
Response<Score> getCreditScoreAsync(Customer customer);
// Asynchronous operation with callback.
Future<?> getQuoteAsync(Customer customer,
AsyncHandler<Score> handler);
}
- Utilisation de la méthode de rappel
- La méthode de rappel requiert un gestionnaire de rappels qui est présenté dans l'exemple suivant. Lors de l'utilisation de la procédure de rappel, une fois qu'une demande est effectuée, le gestionnaire de rappel est chargé de traiter la réponse. La valeur de la réponse est une réponse ou une exception. La méthode Future<?> représente le résultat d'un calcul asynchrone. Elle permet également de vérifier si le calcul est terminé. Lorsque vous souhaitez que l'application détecte si la demande a abouti, appelez la méthode Future.isDone(). Notez que la méthode Future.get() ne fournit pas de réponse porteuse de sens et qu'elle n'est pas similaire à la méthode Response.get().
CreditRatingService svc = ...;
Future<?> invocation = svc.getCreditScoreAsync(customerTom,
new AsyncHandler<Score>() {
public void handleResponse (
Response<Score> response)
{
score = response.get();
// process the request...
}
}
);
- Utilisation de la méthode d'interrogation
- L'exemple suivant présente un client d'interrogation asynchrone :
CreditRatingService svc = ...;
Response<Score> response = svc.getCreditScoreAsync(customerTom);
while (!response.isDone()) {
// Do something while we wait.
}
score = response.get();