Web Services en Axis2 con Spring y Gradle

Recientemente en un proyecto un cliente nos dijo que la interfaz entre nuestros sistemas sería... esperen... sí... un web service. Un web service que ellos invocarían y que por lo tanto nosotros tenemos que implementar. Así que nos dieron un par de archivos WSDL y unos ejemplos de XML para asegurarnos que salga como debe ser (no entiendo para qué, si todas las herramientas de generación de web services se encargan de que el XML siempre salga como debe ser, ¿verdad?).

Cuando tengo que invocar un web service, generalmente uso Axis2. Me ha resultado de lo más sencillo porque consiste simplemente en ejecutar el script   dándole el URI del WSDL y con eso tengo una clase que puedo usar para invocar los servicios (junto con mil clases internas que envuelven los datos dentro de envoltorios intermedios porque parece que los de Axis entendieron OOP como Onion-Oriented Programming). Así que en esta ocasión decidí probar el otro lado de la implementación: publicar un servicio hecho con Axis2.

La primera parte es bastante sencilla y muy similar a la de hacer un cliente: Con el script   se genera el código para el servicio, incluyendo un script de Ant para crear un archivo   que contiene el servicio (detalles más adelante). Aquí en vez de un stub que sirva para invocar el servicio, nos queda una clase con los métodos del servicio, en donde tenemos que meterle código para que hagan algo. Y aquí es donde empieza lo interesante.

Antes de empezar a echar código me puse a investigar cómo iba a ser el deploy de esta cosa. Resulta que Axis2 ofrece un   que se puede aventar en cualquier contenedor de servlets y funciona como una aplicación para publicar web services; simplemente hay que empacar los servicios en formato AAR (supongo que de Axis ARchive) y echarlos dentro del   del directorio "explotado" (o dentro del   antes de meterlo al contenedor). El formato del AAR incluye un archivo   similar a un  , con la definición de los servicios. El script   me genera ese archivo pero pues lo puedo modificar después. Con eso y las clases ya tengo un servicio básico que puedo probar de inmediato.

Una implementación real

Pero una vez que tenemos este esqueleto, qué podemos hacer para implementar un servicio real? Digamos, algo que se conecta a base de datos, que utiliza varios componentes que incluso ya tenemos en otras bibliotecas de nuestros proyectos, que use Spring para conectar dichos componentes, etc?

Para la parte de incluir componentes existentes, simplemente agregamos jars a un directorio   que debe quedar dentro del AAR y estarán disponibles para nuestro servicio. Y para Spring... ah, eso sí es un poco más complicado; resulta que Axis2 tiene soporte para Spring, para integrar de manera sencilla un applicationContext con el servicio que vamos a implementar, pero el soporte es para Spring 2.5, lo cual está muy bien para la gente que sigue programando en 2008, pero para los que estamos en 2013 usando Spring 3.x no sirve de nada. Me consta porque intenté usar este soporte y simplemente ya no funciona porque los componentes de Axis2 para Spring implementan interfaces que fueron eliminadas en Spring 3.

Así que tuve que hacer mi propio componente, después de buscar en los repositorios de Apache para encontrar las implementaciones de los componentes originales de Axis2 para integrar Spring. En mi caso no fue complicado, aunque algo engorroso; tuve que hacer una clase que guardara el application context en una variable estática y que lo cargue de manera sincronizada cuando lo necesita y no existe. Y de paso implementar una interfaz de Axis2 para proveer los objetos que implementan servicios. Ah y lo implementé en Groovy. Algo así:

 

Ahora, para que todo esto funcione, hay que ponerlo en la definición del servicio, por lo que hay que modificar el  :

 

Por cierto, aquí en este ejemplo estoy suponiendo que el archivo de Spring se llama   y se encuentra dentro del directorio raíz del AAR. Y en ese contexto debe existir un bean llamado  , de la clase generada por el wsdl2java donde pongo mi código para implementar el servicio. Ese componente tiene los métodos del servicio y es donde puedo ponerle referencias a otros beans definidos en el application context, tales como DataSources, etc.

El archivo   que mencioné anteriormente, debe estar dentro del   del AAR. Y pues hay que empacar varios jars en   como mencioné anteriormente. Para esto se puede modificar el script de ant; yo preferí hacer un script para construir todo con Gradle, porque eso me permite manejar las dependencias para compilar, ejecutar pruebas, y empacar el AAR.

Compilar, probar, empacar: con Gradle es sencillo

Para que esto funcionara de manera sencilla, primero acomodé todo en el layout estándar para proyectos de Gradle: dentro del directorio raíz del proyecto puse las cosas de esta forma:

src/main/groovy
Aquí va todo el código fuente que yo voy a hacer para el proyecto, junto con los archivos Java generados por el wsdl2java
src/main/resources
Aquí va el application context
src/main/resources/META-INF
Aquí va el services.xml
src/test/groovy
Aquí van mis pruebas, que hice con Spock
src/test/resources
Aquí puedo poner un application context de prueba con mockups o componentes configurados de forma distinta al real

Y necesito por supuesto un  , que va más o menos así:

 

Es un script de Gradle bastante simple; lo único que tiene fuera de lo común es la configuración   (que puede llamarse como sea), la cual hice para definir como dependencias ahí los jars que quiero incluir en el AAR, y tuve que modificar la configuración del jar para incluir esas dependencias y que se metan al directorio  .

Cuando ejecuto  , al final me queda un archivo con extensión   dentro de  , el cual simplemente debo meter en axis2/WEB-INF/services (si uso Tomcat, esa ruta está dentro de   una vez que arrojé el   ahí mismo) para publicar mi servicio.

El archivo AAR contendrá los jars de Spring, log4j, slf4j, y cualquier otra cosa que defina (directa o indirectamente) como dependencia de la configuración   en el script de Gradle. Es necesario repetir algunas cosas que están en la configuración de compilación, pero es que el AAR no debe incluir las bibliotecas de Axis2 porque esas ya están en el  .

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Muy buena explicacion

Yo apenas realice un Servicio WEB usando Spring y Apache CXF, me parecio de lo mas practico y facil de implementar, de hecho para probarlo puedes usar el Test de Spring y el WSDL lo genera al vuelo usando las interfaces.

Saludos

Imagen de ezamudio

WSDL

El problema aquí es que no podía hacer el web service como a mí se me ocurriera sino que el cliente ya me dio un WSDL porque ellos ya tienen hecho su desarrollo y solamente quieren invocar el web service que tengo que implementar, con su cliente que ya está hecho y no le van a hacer modificaciones. Por lo tanto tengo que apegarme al formato de los datos que ya tienen; por eso usé Axis2, porque el wsdl2java te genera los componentes para el servicio a partir del archivo WSDL.

Cuando voy a hacer un web service con el formato que yo quiera, simplemente diseño el componente, le pongo las anotaciones de   y demás, y lo publico con el   de Spring, es lo más simple que he encontrado.

OK

Siendo asi, pues ni hablar. Creo que con CXF tambien puedes armar tus servicios a partir de un WSDL, no estoy seguro pero lo voy a investigar. También voy a checar si AXIS 2 me ofrece mejor rendimiento que CXF, ya que segun se CXF implementa la interface Future para el manejo de Hilos y concurrencia.

Saludos.

Imagen de ingscjoshua

Y con java 6??

Y ya intentaron hacer un cliente con java 6??

Imagen de ezamudio

Hacer un cliente con java 6 es muy fácil. Alguien lo puso en su blog aquí hace mucho tiempo. Pero nuevamente: yo aquí estoy hablando de publicar un servicio, a partir de un WSDL, no de hacer un cliente.

Ayuda

ezamudio pilas ayudame con mi blog aqui te lo dejo Problemas con jframe al momento de maximizarlo

Imagen de jsmaster

Axis y SAP WS

Si, realmente axis me parece de los mas simple, cierto día me toco implementar WS que me entreganban, a los cuales tenia acceso al SAP, y me impresionó la simplicidad con la que se manipula.