jueves, 18 de julio de 2013

Agregando un interceptor de mensajes SOAP XML (SOAP JaxWs Handler) con Spring de lado del cliente.

La idea con este artículo es mostrar como agregar un "handler" a nuestras peticiones SOAP, las cuales están siendo invocadas con JaxWs.

Con el "handler" se podrá interceptar el mensaje, ya sea cuando se envia la petición (se intercepta antes de enviar) ó cuando se recibe la respuesta  (se intercepta después de recibirla), esto puede servir para modificar la información de la cabecera del mensaje SOAP, con el fin de mandar información especial al servidor, ó simplemente para imprimir el mensaje "crudo" del XML con fines de monitoreo. El objetivo por el momento será solamente imprimir el XML del mensaje.

En Spring existe una forma de inyectar un objeto al bean que implementa la clase proxy generada por la herramienta wsdl2java, este objeto relacionará al "handler" con el webservices a través de la interface  HandlerResolver, esta interface es la que "encadena" a la verdadera clase que interceptará los mensajes. Esta debe implementar a SOAPHandler.

1. Creamos la clase DelegateSOAPHandler que implementará a la clase SOAPHandler.
public boolean handleMessage(SOAPMessageContext context);

El método handleMessage es invocado cuando una petición ó respuesta SOAP es procesada. El método getMessage() devuelve un objeto de tipo SOAPMessage, con el cual podemos acceder al contenido del mensaje SOAP y por lo tanto a modificarlo o sencillamente leerlo. Al final se debe regresar true, de lo contrario si se tienen enlazados más de un "handler", el resto ya no serán procesados.

El método public void handleMessageToLog(SOAPMessageContext context); se ha creado para generar la impresión de nuestro XML dentro del archivo log. Se agrego un poco más de código para darle un formato más claro al mensaje XML.

public boolean handleFault(SOAPMessageContext context);

El método handleFault, procesa los errores que sucedan en la comunicación SOAP. De la misma manera, al final regresamos true.

2. Creamos la clase DefaultHandlerResolver que implementará a la clase HandlerResolver.
Todos los objetos Handler que sean regresado en la lista por medio del método public List getHandlerChain(), seran asociados y usados por nuestro objeto proxy (port object) de nuestro servicio web. En otras palabras, si deseas asociar varias clases del tipo DelegateSOAPHandler. Para poder inyectar nuestra dependencia, se ha creado un método "setter".

3.- Configuracion de beans: applicationContext.xml
Para asignar el bean HandlerResolver, dentro del bean MetaDataWSInformation se debe agregar la propiedad handlerResolver-ref, por medio de esta propiedad, inyectamos el bean handlerResolver el cual es del tipo DefaultHandlerResolver. A su vez al bean handlerResolver por medio de la propiedad handlerList-ref se le inyecta el bean listHandler, quien implementa a SOAPHandler, justamente el objeto quien interceptara las peticiones de la comunicación SOAP.

Con esto ya podemos invocar nuestro objeto proxy que nos provee el bean MetaDataWSInformation para hacer una prueba de que todo funcione correctamente.

Abajo se muestra un ejemplo del XML de una petición y otro de la respuesta.

Por cierto, preferí dejar algunas palabras en inglés, ya que se indexa mejor la publicación, y por otra parte, al traducirlas pierden un poco el sentido :-].

Referencias:
  • http://docs.oracle.com/cd/E15051_01/wls/docs103/webserv_adv/handlers.html
  • http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Fcwbs_jaxwsclients.html
  • http://www.jroller.com/gmazza/entry/jaxws_handler_tutorial

0 comentarios:

Publicar un comentario