Axis2: Invocación de Servicios Web usando distintos MEP

En este tutorial aprenderemos a crear clientes más avanzados de servicios Web con el API de cliente de Axis2

Axis2: Invocación de Servicios Web usando distintos MEP

Introducción.

En este tutorial vamos a llevar a la práctica la invocación de servicios web a través de cada uno de los patrones de intercambios de mensajes (MEP) definidos en WSDL 2.0.
Para ello, vamos a realizar una aplicación de escritorio en donde utilizaremos el API de cliente de Axis2 para invocar la única operación que expone el servicio Web construido en un tutorial anterior » Spring WS: Creación de Servicios Web con Spring con cada uno de los MEP.

Manos a la obra con la aplicación cliente:

El siguiente ejemplo está construido bajo el siguiente entorno:

  • HP Pavilion.
  • Windows Vista Home Premium.
  • Eclipse Ganymede.
  • Java 6.
  • Tomcat 6
  • Maven 2.
  • Plugin Maven 4QE para Eclipse.
  • Axis2 1.4.1

Si después de leer este tutorial quieres probarlo tu mismo, en los siguientes enlaces te dejo lo necesario:

  • El servicio web en formato WAR, por lo que simplemente deberás desplegarlo en tu servidor o contenedor favorito.
  • La parte cliente (proyecto Maven2 y Eclipse) que vemos en este tutorial.

Para poder utilizar los servicios que ofrece un web service necesitamos conocer su descripción o WSDL.
Esta casi siempre es publicada por el servicio web a través de una URL, por ejemplo: http://localhost:8080/bibliotecaWS/bibliotecaWS.wsdl)

WSDL del servicio web a invocar con distintos MEP:



    
        
            
                
                    
                        
                        
                    
                
            
            
                
                    
                    
                    
                
            
            
                
                    
                        
                    
                
            
            
                
                    
                        
                        
                        
                        
                    
                
            
        
    
    
        
    
    
        
    
    
        
            
            
        
    
    
        
        
            
            
                
            
            
                
            
        
    
    
        
        
            
            
                
            
            
                
            
        
    
    
        
            
        
        
            
        
    


Si nos fijamos en el WSDL observamos que (de cara al código fuente que veremos a continuación):

  1. El servicio Web tiene dos
    Text
    wsdl:port

    de comunicación (líneas 83 a 88)

  2. Sólo hay definido un Servicio Web (líneas 82-89)
  3. Sólo hay definida una operación
    Text
    BooksInfo

    (líneas 72 a 80)

  4. El formato de la petición a la única operación es el siguiente (líneas 12-26):

  
            Servicios Web  
            avanzado  
         
    

Text
Axis2MEPApp

: Ejemplo del uso el API de cliente de Axis2 para conseguir invocar un método con distintos patrones de intercambio de mensajes (MEP).

A continuación contruiremos una aplicación de escritorio en donde al ejecutarla podremos elegir el método de invocación al servicio Web: In-Out sincrono, In-Out asíncrono, etc.

El código fuente está autocomentado.

package com.autentia.tutoriales.axis2.cliente;

import java.net.URL;
import javax.xml.namespace.QName;
import org.apache.axiom.om.*;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AxisCallback;
import org.apache.axis2.context.ConfigurationContext;

/**
 * Ejemplo del uso el API de cliente de Axis2 para conseguir invocar un método
 * con distintos patrones de intercambio de mensajes (MEP).
 * @author Carlos García. Autentia
 */
public class Axis2MEPApp  {
	
    public static void main(String[] args) {
    	char userOption = '0';
    	
    	try {
    		while ((userOption < '1') || (userOption > '4')){
	    		System.out.println("Ejemplo de invocación a servicios web con distintos Message Exchange Patterns:");
	    		System.out.println("(1) MEP In-Out   Síncrono");
	    		System.out.println("(2) MEP In-Out   Asíncrono");
	    		System.out.println("(3) MEP In-Only. Recepción y procesamiento del mensaje asegurada.");
	    		System.out.println("(4) MEP In-Only. Recepción y procesamiento del mensaje no asegurada.");
	    		System.out.println("Seleccione una opción (1, 2, 3, 4):");
	    		userOption = (char) System.in.read();
    		}
    		
    		// Usamos la configuración por defecto de Axis2
    		ConfigurationContext context	 = null; 															 
        	
        	// URL del WSDL
        	URL	wsdlURL	 = new URL("http://localhost:8080/bibliotecaWS/bibliotecaWS.wsdl");	
        	
        	// Podría ser Null pues sólo hay un servicio en el WSDL
        	QName serviceName = new QName("https://adictosaltrabajo.com/spring/ws/schemas", "bibliotecaWSService");						
        	
        	// El WSDL tiene 2 Port elegimos uno.
        	String	portName = "bibliotecaWSSoap12";
        	
        	// Clase cliente básica (No tiene acceso a operaciones más avanzadas como OperationClient)
        	ServiceClient wsClient = new ServiceClient(context, wsdlURL, serviceName, portName);
    		
        	// Operación a invocar    		
	    	QName operation = new QName("https://adictosaltrabajo.com/spring/ws/schemas", "BooksInfo");
	    	
	    	// Obtenemos la petición a enviar al servicio web
	    	OMElement	  request   = Axis2MEPApp.getRequest("Servicios Web", "avanzado");    	
    		
	    	
    		switch (userOption){
    			case '1': 
    		    	OMElement  response  = wsClient.sendReceive(operation, request);
    		    	 
    		    	// Imprimimos la respuesta
    		    	System.out.println(response);
    				break;
    			case '2': 
    		    	// CallBack que recibirá la respuesta
    		    	AxisCallback callback = new MyAxisCallback();
    		    	
    		    	wsClient.sendReceiveNonBlocking(operation, request, callback);
    		    	
    		    	for (int i = 0; i < 5; i++){
    		    		System.out.println("Continuamos trabajando en otras cosas mientras el servidor procesa la petición" +  
    		    						   "(tiempos de red + proceso + configuraciones poco optimas de servidores + ...) y nos responde");
    		    		Thread.sleep(100);
    		    	}
    				break;
    			case '3': 
    		    	wsClient.sendRobust(operation, request);
    				break;
    			case '4': 
    		    	wsClient.fireAndForget(operation, request);
    		    	
    		    	// Esperamos un poco para que le de tiempo a enviar la petición (se envia en background)
    		    	Thread.sleep(200);
    				break;    				
    		}
    	} catch (Exception ex){
    		System.out.println(ex); // Es sólo un tutorial, no me preocupo de gestionar bien las excepciones.
    	}
    	
    	
    	System.out.println("FIN DE LA APLICACION");
    }


    /**
     * @param  categoria Categoría del libro a consultar
     * @param  nivel	 Nivel del libro a consultar, valores permitidos: basico, medio, avanzado
     * @return Devuelve la petición a enviar al servicio web.
     */
	private static OMElement getRequest(String categoria, String nivel){
    	/*
			  
				Biología
				basico
			
			
 			Nota, también se podría hacer desde un String
 				StAXOMBuilder builder = new StAXOMBuilder(new ByteArrayInputStream("El xml...".getBytes()));
				OMElement	  request = builder.getDocumentElement();
    	 */    	
    	OMFactory factory = OMAbstractFactory.getOMFactory();	
    	OMNamespace namespace  = factory.createOMNamespace("https://adictosaltrabajo.com/spring/ws/schemas", "");
    	OMElement request      = factory.createOMElement("BooksInfoRequest", namespace);
    	OMElement categoryNode = factory.createOMElement("categoria",		 namespace);
    	OMElement nivelNode	   = factory.createOMElement("nivel",			 namespace);
    	
    	categoryNode.addChild( factory.createOMText(categoria) );
    	nivelNode.addChild(    factory.createOMText(nivel) );
    	
    	request.addChild(categoryNode);
    	request.addChild(nivelNode);
    	
    	return request;
    }   
}

Text
MyAxisCallback

: Implementación de un AxisCallback para las operaciones asíncronas.

package com.autentia.tutoriales.axis2.cliente;

import org.apache.axiom.om.OMElement;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.client.async.AxisCallback;

/**
 * Implementación de un AxisCallback para las operaciones asíncronas.
 * @author Carlos García. Autentia.
 */
public class MyAxisCallback implements AxisCallback {
	
	/* 
	 * @see org.apache.axis2.client.async.AxisCallback#onComplete()
	 */
	public void onComplete() {
		System.out.println("onComplete");
	}

	/* 
	 * @see org.apache.axis2.client.async.AxisCallback#onFault(org.apache.axis2.context.MessageContext)
	 */
	public void onFault(MessageContext context) {
		System.out.println("onFault");
		
		OMElement payload = context.getEnvelope().getBody();
		System.out.println(payload);				
	}			
	
	/* 
	 * @see org.apache.axis2.client.async.AxisCallback#onError(java.lang.Exception)
	 */
	public void onError(Exception ex) {
		System.out.println("onError " + ex.toString());
	}

	/* 
	 * @see org.apache.axis2.client.async.AxisCallback#onMessage(org.apache.axis2.context.MessageContext)
	 */
	public void onMessage(MessageContext context) {
		System.out.println("onMessage");
		OMElement payload = context.getEnvelope().getBody();
		System.out.println(payload);
	}    
}

Archivo de configuración de Maven 2:

Text
pom.xml

:

Por si te sirve de plantilla para otros proyectos, te dejo el

Text
pom.xml

del proyecto.



	4.0.0
	com.autentia.tutoriales
	bibliotecaWSClienteAxis2
	jar
	1.0-SNAPSHOT
	bibliotecaWSClienteAxis2
	https://adictosaltrabajo.com
	
	
		
			
				maven-compiler-plugin
				
					1.6
					1.6
					UTF-8
				
			

		
	
	
		
		
			org.apache.axis2
			axis2-kernel
			1.4.1
		
	


Referencias

Conclusiones

Como veis el API de cliente Axis2 es bastante facil de usar y comprender, siendo además bastante ligero en cuanto número de clases e interfaces.

Aunque con la clase

Text
ServiceClient

podemos satisfacer la mayoría de nuestras necesidades de cliente, tenemos disponible la clase

Text
OperationClient

para operaciones más avanzadas, como por ejemplo manipulación de cabeceras.

Existen otros patrones MEP en los que es el servidor el que inicia la comunicación Out-Only, etc. ver WSDL 2.0, pero estos se consigen de la misma forma
que la que ya hemos visto, siempre y cuando el servidor conozca las direcciones de los clientes. Si estais interesados podeis mirar los ejemplos de la distribución para profundizar más….

Carlos García Pérez. Creador de MobileTest, un complemento educativo para los profesores y sus alumnos.

cgpcosmad@gmail.com

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Técnico especialista en informática de empresa (CEU). Ingeniero Técnico en Informática de Sistemas (UPM) Creador de MobileTest, Haaala!, Girillo, toi18n. Charla sobre desarrollo de aplicaciones en Android. @cgpcosmad

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

22/06/2026

Juan Antonio Jiménez Torres

Vamos a instrumentalizar un SDD para un microservicio bancario. En este artículo sobre SDD - Spec Driven Development, instrumentalizado sobre OpenSpec vamos a construir una PoC de algo más serio que una tabla periódica. Un microservicio bancario muy simplificado que gestione cuentas y permita hacer transferencias

16/06/2026

Juan Antonio Jiménez Torres

Este es el segundo artículo sobre SDD, Spec Driven Development, instrumentalizado sobre OpenSpec. Pero esta vez nos acercaremos usando softwere gratuito. Por un lado OpenCode en lugar de ClaudeCode y usando el modelo gratuito Gemma4 de Google en lugar de otros de pago.

08/06/2026

Juan Antonio Jiménez Torres

Aprenderemos sobre SDD – Spec Driven Development instrumentalizado sobre OpenSpec. Haremos un primer acercamiento usando ClaudeCode con Sonnet, para luego, en un artículo posterior pasarnos a la versión gratuita de OpenCode con Gemma4