viernes, 6 de noviembre de 2009

MANEJO DE 'WEB SERVICE' CON 'AXIS2'.

Hace un tiempo posteè sobre el manejo de Web Service con AXIS1, esta vez mostraré el manejo de Web Service (Su consumo) pero con AXIS2. Este Framework AXIS2 a diferencia de su versión anterior AXIS1 permite un mejor manejo de los Web Service Orientados a Objetos, ya que en la versión anterior de AXIS los Objetos del Service enviados como parámetros por el Web Service, se podían regenerar desde un cliente WS pero para poder parsearlos se necesita de forma obligada el número de serialVersionUID (Para poder comprobar que es el mismo objeto) , aquí AXIS1 era débil. AXIS2 supero eso ya que no tiene este traspié. AXIS2 solamente posee un problema al momento de la generación del cliente WS que mas adelante mostraremos y solucionaremos.

Al igual que el ejemplo posteado con AXIS1 mostraré la generación del Cliente WS y consumo de dichos procesos:

/********** PROCESOS 'WS' **********/
//Probando 'SUMA'.
clienteWS.getResultadoSuma( numero_01, numero_02, accesoWS );

//Probando 'RESTA'.
//clienteWS.getResultadoResta( numero_01, numero_02, accesoWS );

//Probando 'MULTIPLICACION'.
//clienteWS.getResultadoMultiplicacion( numero_01, numero_02, accesoWS );

//Probando 'DIVISION'.
//clienteWS.getResultadoDivision( numero_01, numero_02, accesoWS );

//Probando 'obtenerUsuario'.
//clienteWS.getObjetoUsuario( accesoWS );

//Probando 'obtenerListaUsuarios'.
//clienteWS.getListaUsuarios( accesoWS );;
/***********************************/

Los pasos son los siguientes:

1.- Tenemos el WSDL ya generado del servidor “UsuarioServiceImpl.wsdl” , este WSDL esta en la ruta: WebContent/wsdl/UsuarioServiceImpl.wsdl. En base a esta ruta generaremos por medio de consola el Cliente AXIS2, pero tendremos que configurar las variables de entorno antes.

2.- Bajarte la ultima versión de AXIS2: http://ws.apache.org/axis2/1_5_1/installationguide.html

3.- Ubicarla en una ruta en tu PC: “D:\JAVA\Axis\axis2-1.5.1”

4.- Registrar las variables de entorno (Tanto en Usuario como en Sistema):



5.- Generar el cliente AXIS2 desde consola aplicando el siguiente còdigo desde la ruta raiz del proyecto trabajado:

%AXIS2_HOME%/bin/WSDL2Java -p org.java.service -uri WebContent/wsdl/UsuarioServiceImpl.wsdl -s



6.- En este momento AXIS2 genera un error:

Es posible que cuando se desee generar un cliente JAVA con AXIS2 en base a un WSDL, uno encuentre con un error así:

Unexpected subelement 'XXXX'

Esto se debe a que AXIS2 genera el Cliente WS de una forma no totalmente correcta. Ya que confunde los NameSpaceURI. Supongamos como en este caso que el Servidor WS posee dos paquetes:

- PAQUETE DEL OBJETO: org.java.bean
- PAQUETE DEL WS: org.java.servidor.ws

Al momento de la generación del Cliente WS con AXIS2, los NameSpaceURI se invierten y quedan de la siguiente manera:

- NAMESPACE APUNTANDO AL OBJETO: “http://bean.java.org"
- NAMESPACE APUNTANDO AL WS: "http://ws.servidor.java.org"

Aquí esta el problema y la solución seria buscar la clase 'Stub' generada, en este caso 'ConsultaWSServiceStub' y en ella buscar por cada Objeto que se trabaje su:

static MY_OBJETO parse:

/**
* Factory class that keeps the parse method
*/
public static class Factory{

/**
* static method to create the object Precondition: If this object is an element, the
* current or next start element starts this object and any intervening reader events
* are ignorable If this object is not an element, it is a complex type and the reader
* is at the event just after the outer start element Postcondition: If this object is
* an element, the reader is positioned at its end element If this object is a complex
* type, the reader is positioned at the end element of its outer element
*/
public static Usuario parse( javax.xml.stream.XMLStreamReader reader ) throws java.lang.Exception{

Y cambiar el NameSpace para cada campo de > cada Objeto trabajado, de la siguiente forma:

AQUI SE DA EL 'ERROR':

while( !reader.isStartElement() && !reader.isEndElement() )
reader.next();
if( reader.isStartElement() &&
new javax.xml.namespace.QName( "http://bean.java.org", "nombre" ).equals( reader.getName() ) ){
nillableValue = reader.getAttributeValue( "http://www.w3.org/2001/XMLSchema-instance", "nil" );
if( !"true".equals( nillableValue ) && !"1".equals( nillableValue ) ){
java.lang.String content = reader.getElementText();
object.setNombre( org.apache.axis2.databinding.utils.ConverterUtil.convertToString( content ) );
}
else{
reader.getElementText(); // throw away text nodes if any.
}
reader.next();
} // End of if for expected property start element
else{
// A start element we are not expecting indicates an invalid parameter was
// passed throw new org.apache.axis2.databinding.ADBException( "Unexpected subelement " + reader.getLocalName() );
}

AQUI SE DA EL 'SOLUCION':

while( !reader.isStartElement() && !reader.isEndElement() )
reader.next();
if( reader.isStartElement() &&
new javax.xml.namespace.QName( "http://ws.servidor.java.org", "nombre" ).equals(
reader.getName() ) ){
nillableValue = reader.getAttributeValue( "http://www.w3.org/2001/XMLSchema-instance", "nil" );
if( !"true".equals( nillableValue ) && !"1".equals( nillableValue ) ){
java.lang.String content = reader.getElementText();
object.setNombre(
org.apache.axis2.databinding.utils.ConverterUtil.convertToString( content ) );
}
else{
reader.getElementText(); // throw away text nodes if any.
}
reader.next();
} // End of if for expected property start element
else{
// A start element we are not expecting indicates an invalid parameter was
// passed throw new org.apache.axis2.databinding.ADBException( "Unexpected subelement " + reader.getLocalName() );
}

7.- Creamos la clase: org/java/client/ClienteWS_Generado.java y vamos descomentando y ejecutando los procesos anteriormente nombrados uno por uno para probar su manejo. Recordar que primero se tiene que desplegar el demo del 'Proyecto Servidor' que es parte del demo posteado llamado: Ejemplo Web Service con JAX-WS , para poder probar sin problemas el Cliente WS con AXIS2.

Para mayor detalle descargar el ejemplo completo: AQUÌ.

2 comentarios:

sergio dijo...

Estimado, no logro entender cual fue la modificacion que se realizo a los namespace.

favor aclarar como estaba y como se dejo finalmente.

Saludos y gracias por el contenido del blog

JAVAMAN dijo...

Que tal Sergio lo explicado sobre los NameSpace es si se cruzan con al ejecutar tu cliente WS con AXIS2, con el error: Unexpected subelement
este error es bien raro, por eso explico en el POST como solucionar, el error apunta al nombre de los NameSpace (Paquetes declarados en el WebService Servidor), que al estar los objetos de negocio en diferente paquete que la clase implementadora, causa algunas veces que aparesca dicho error al mapear el WSDL con AXIS2. Se soluciona solo apuntando al NameSpace que hace referencia al paquete de la clase Implementadora.