miércoles, 27 de marzo de 2013

AXIS & Maven

Vamos a dejar los pasos necesarios para crear un web service utilizando una tecnología vieja como AXIS:

1. Creamos un arquetipo web con maven

mvn archetype:generate -DgroupId=com.ws -DartifactId=WSProject -DarchetypeArtifactId=maven-archetype-webapp


2. Luego creamos la clase que sera la interface del WS

public interface Calculator {
    int add (int x, int y);
    int subtract(int x, int y);
}


3. Luego creamos el WSDL en base a dicha clase

Armamos una carpeta con los libs del proyecto AXIS, ej E:\cliente_prueba y ahi tiramos todos los libs de dicho proyecto que podemos descargar desde apache

E:\cliente_prueba>set classpath=%CLASSPATH%;axis.jar;axis-ant.jar;commons-discovery-0.2.jar;commons-logging-1.0.4.jar;jaxrpc.jar;log4j-1.2.8.jar;saaj.jar;wsdl4j-1.5.1.jar;e:\cliente_prueba

E:\cliente_prueba>java org.apache.axis.wsdl.Java2WSDL -o prueba.wsdl -n urn:org.axis.ws -l http://localhost:8080/axis/services/calculator org.axis.ws.Calculator


4. Luego con el wsdl (prueba.wsdl) podemos generar las clases necesarias

E:\cliente_prueba>java org.apache.axis.wsdl.WSDL2Java -s prueba.wsdl

Entre las clases que genera, vamos a tener una llamada: CalculatorSoapBindingImpl y es esta la que va a tener nuestra implementacion del WS.

Algunos tips:

o – output folder -> src
p – package for generated classes -> org.kamal.wssample.ws.generated
s – generate server side classes as well


5. Luego agregamos dichas dependencias en el POM

<!-- AXIS dependency  -->

<dependency>
<groupId>axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
</dependency>

<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>

<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.2</version>
</dependency>

<dependency>
<groupId>axis</groupId>
<artifactId>axis-wsdl4j</artifactId>
<version>1.5.1</version>
</dependency>

<dependency>
<groupId>axis</groupId>
<artifactId>axis-saaj</artifactId>
<version>1.4</version>
</dependency>


6. Luego agregamos el server-config.wsdd dentro de /WEB-INF/


Para que nuestro servicio web se despliegue automáticamente cuando hagamos el despliegue del WAR en nuestro servidor de aplicaciones, deberemos crear un archivo llamado server-config-wsdd dentro de la carpeta /WEB-INF. Este archivo indicará al servidor de aplicaciones que clases definen un WS y como están configuradas. Además será donde se pueda integrar cualquier tipo de configuración y manejadores (handlers) para los WS.

La parte que engloba la etiqueta service del archivo wsdd es lo que importa. Lo demás es fijo para todos los WS que hagamos. Si queremos desplegar más de un WS en un mismo WAR, debemos añadir más etiquetas service a nuestro descriptor server-config.wsdd.

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

<globalConfiguration>
<parameter name="adminPassword" value="admin"/>
<parameter name="attachments.Directory" value="D:\Tomcat5.0\webapps\axis\WEB-INF\attachments"/>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="sendXsiTypes" value="true"/>
<parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
<parameter name="sendXMLDeclaration" value="true"/>
<parameter name="axis.sendMinimizedElements" value="true"/>
<parameter name="axis.enableListQuery" value="false"/>

<requestFlow>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="session"/>
</handler>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="request"/>
<parameter name="extension" value=".jwr"/>
</handler>
</requestFlow>
</globalConfiguration>

<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>

<service name="AdminService" provider="java:MSG">
<parameter name="allowedMethods" value="AdminService"/>
<parameter name="enableRemoteAdmin" value="false"/>
<parameter name="className" value="org.apache.axis.utils.Admin"/>
<namespace>http://xml.apache.org/axis/wsdd/</namespace>
</service>

<service name="Version" provider="java:RPC">
<parameter name="allowedMethods" value="getVersion"/>
<parameter name="className" value="org.apache.axis.Version"/>
</service>

<service name="CalcService" provider="java:RPC" style="wrapped" use="literal">
   <operation name="add" qname="ns15:Add" returnQName="ns15:result" returnType="xsd:int" xmlns:ns15="http://simbit.com/simsave1.0/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<parameter qname="ns15:in0" type="xsd:int"/>
<parameter qname="ns15:in1" type="xsd:int"/>
</operation>

<operation name="subtract" qname="ns15:Subtract" returnQName="ns15:result" returnType="xsd:int" xmlns:ns15="http://simbit.com/simsave1.0/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<parameter qname="ns15:in0" type="xsd:int"/>
<parameter qname="ns15:in1" type="xsd:int"/>
</operation>

<parameter name="allowedMethods" value="add subtract"/>
<parameter name="wsdlPortType" value="Calculator"/>
<parameter name="className" value="org.axis.ws.generated.CalculatorSoapBindingImpl"/>
<parameter name="wsdlServicePort" value="CalcService"/>
<parameter name="wsdlTargetNamespace" value=""/>
<parameter name="wsdlServiceElement" value="CalculatorService"/>

</service>

<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
</transport>

<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>

</deployment>


7. Modificamos el WEB:XML y agregamos una seccion de AXIS:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!-- Axis section -->
<display-name>Apache-Axis</display-name>
<servlet>
<servlet-name>AxisServlet</servlet-name>
<display-name>Apache-Axis Servlet</display-name>
<servlet-class> org.apache.axis.transport.http.AxisServlet
</servlet-class>
</servlet>
<servlet>
<servlet-name>AdminServlet</servlet-name>
<display-name>Axis Admin Servlet</display-name>
<servlet-class> org.apache.axis.transport.http.AdminServlet
</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet>
<servlet-name>SOAPMonitorService</servlet-name>
<display-name>SOAPMonitorService</display-name>
<servlet-class> org.apache.axis.monitor.SOAPMonitorService
</servlet-class>
<init-param>
<param-name>SOAPMonitorPort</param-name>
<param-value>5001</param-value>
</init-param>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SOAPMonitorService</servlet-name>
<url-pattern>/SOAPMonitor</url-pattern>
</servlet-mapping>

</web-app>

8. Listo, levantamos el tomcat y en por ejemplo http://localhost:8081/WSAxisProject/services vamos a ver el ws desplegado.

NOTA: Si lo levantamos con un tomcat 6 la primera vez que listamos los servicios va a lanzar un error que no se sabe porque pero anda a la perfeccion. En cambio con Tomcat 5 no lanza dicho error. El error tiene pinta que sale mediant eun system.out.println y no por logs

java.lang.NoClassDefFoundError: org/apache/axis/deployment/wsdd/WSDDProvider
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1667)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.apache.axis.deployment.wsdd.WSDDProvider.loadPluggableProviders(WSDDProvider.java:106)
at org.apache.axis.deployment.wsdd.WSDDProvider.<clinit>(WSDDProvider.java:74)
at org.apache.axis.deployment.wsdd.WSDDService.makeNewInstance(WSDDService.java:437)
at org.apache.axis.deployment.wsdd.WSDDDeployment.getDeployedServices(WSDDDeployment.java:503)
at org.apache.axis.configuration.FileProvider.getDeployedServices(FileProvider.java:296)
at org.apache.axis.transport.http.AxisServlet.reportAvailableServices(AxisServlet.java:482)
at org.apache.axis.transport.http.AxisServlet.doGet(AxisServlet.java:260)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.axis.deployment.wsdd.WSDDProvider
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 37 more


9. Se podrá descargar el proyecto en:

https://gwt-spring-hibernate-maven.googlecode.com/svn/trunk/WSAxisProject