Hasta ahora el soporte de Web services de Java, aunque muy potente era muy rudimentario y complejo de configurar, requiriendo como podemos comprobar en el manual de Axis multitud de pasos y conocimientos. La nueva especificación jsr-181 que se ha añadido a Java 6 (JAX-WS 2.0) simplifica el desarrollo de servicios web, pero para los que se encuentren, como es mi caso atrapados aún en Java 5, XFire ofrece una implementación de dicha especificación, permitiéndonos simplificar el proceso dramaticamente.
A continuación un mecanismo sencillo para implementar un servicio Webservice gracias a Xfire y usando las anotaciones @WebServices, @WebMethod, @WebParam, @WebResult.
Configuración del sistema
- En primer lugar, declaramos en Maven las dependencias que necesitamos:
<dependency> <groupId>org.codehaus.xfire</groupId> <artifactId>xfire-java5</artifactId> <version>1.2.6</version> </dependency>
- Modificamos el web.xml para declarar el servlet encargado de manejar las peticiones SOAP.
<servlet> <servlet-name>XFire</servlet-name> <display-name>XFire Servlet</display-name> <servlet-class> org.codehaus.xfire.transport.http.XFireConfigurableServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>XFire</servlet-name> <url-pattern>/servlet/XFireServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>XFire</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
- Creamos el fichero de configuracion XFire localizado por defecto en /META-INF/xfire/services.xml, para indicar que clases Java van a ofrecer una interfaz webservice:
<beans xmlns="http://xfire.codehaus.org/config/1.0"> <service> <serviceClass> com.viavansi.motorformularios.handler.MotorFormularioRemoteApi </serviceClass> <serviceFactory>jsr181</serviceFactory> </service> </beans>
- Utilizamos anotaciones sobre la clase o interfaz que tiene los métodos que deseamos publicar como servicios web.
@WebService( name= «MotorFormularios»)
public interface MotorFormularioRemoteApi extends Remote {
@WebMethod(operationName=»execute», action=»urn:ExecuteRequest»)
@WebResult(name=»response» )
public Response execute(@WebParam Request request) throws RemoteException;
- Arrancamos el servidor y comprobamos que efectivamente el servicio esta publicado y funciona correctamente accediendo a WSDL http://localhost:8080/services/MotorFormularios?WSDL
- Una vez publicado el servicio web, y suponiendo que tenemos las interfaces Java, ya no se requiere crear las clases proxy webservice. El mecanismo que podemos utilizar en el cliente es muy similar al utilizado con RMI, nos basta con conocer la interfaz java y la url del servicio web.
// utilizamos el conector WebServices.
Service serviceModel = new ObjectServiceFactory().create(MotorFormularioRemoteApi.class);
// recuperamos la interfaz webservice.
MotorFormularioRemoteApi rmiApi = (MotorFormularioRemoteApi) new XFireProxyFactory().create(serviceModel, url);
- Algunos problemas o limitaciones de esta solución:
La principal limitación de esta solución es que las peticiones codificadas como RPC no estan soportadas por XFire, por lo que para poder integrar con clientes Axis es necesario modificar el tipo de petición de RPC/Encoded a WRAPPED/Literal.
El control de errores en XFire es en ocasiones demasiado criptico, como ejemplo, en el caso de que el SOAP no se pueda procesar debido al problema comentado antes la excepción que se produce es: {http://xml.apache.org/axis/}stackTrace:Index: 1, Size: 1
Actualmente XFire aún no pasa el test de compatibilidad JSR 181 1.0 TCK.