A financial Safety Net Payday loans How much can you borrow

Servicios web con Apache CXF

mundo-con-procesamientoApache CXF es un framework de servicios de Software Libre. CXF nos ayuda a construir y desarrollar servicios utilizando JAX-WS como API de programación. Estos servicios pueden hablar una gran variedad de protocolos como SOAP, XML/HTTP, HTTP RESTful, o CORBA, y pueden trabajar sobre transportes como HTTP, JMS o JBI.

Características de Apache CXF

Las características principales de CXF son:

  • Soporte para estándares de Servicios Web: CXF soporta varios estándares de servicios web incluyendo a SOAP, el Perfil Básico, WSDL, WS-Addressing, WS-Policy, WS-ReliableMessaging y WS-Security.
  • Interfaces: CXF soporte varios modelos de programación como "interfaz". CXF implementa el API JAX-WS. También incluye una "interfaz simple" que permite crear clientes y endpoints sin utilizar anotaciones. CXF soporta el desarrollo por contrato primero con WSDL, y el desarrollo por código primero comenzando desde Java.
  • Facilidad de uso: CXF está diseñado para ser intuitivo y facil de usar. Hay APIs simples para construir servicios comenzando por el código, plug-ins de Maven para integrar esta herramienta, soporte para el API JAX-WS, soporte de XML de Spring 2.0 para facilitar la configuración, y mucho más.
  • Soporte para protocolos binarios y legacy: CXF fue diseñado para proveer una arquitectura extensible que no sólo soporte XML sino también otros binding no-XML, como JSON y CORBA, en combinación con cualquier tipo de transporte.

Construcción de un servicio web con Apache CXF

Para ejemplificar su uso vamos a construir un servicio web partiendo de código Java (con anotaciones JAX-WS). Luego usaremos Spring y CXF para crear el servicio web sobre Tomcat. Por último, crearemos un cliente para el servicio web usando CXF. ¡Manos a la obra!

Creando el servicio web

Crearemos un servicio web "HolaMundo" que devuelva un saludo personalizado. Todas las clases las crearemos dentro de un módulo web (WAR), el cual desplegaremos en Tomcat. Los pasos a seguir serán los siguientes:

  1. Crear la interfaz del servicio web, HolaMundo.java
  2. Crear la implementación del servicio web, HolaMundoImpl.java
  3. Crear el archivo de configuración de Spring, applicationContext.xml
  4. Configurar el archivo web.xml, en donde agregaremos el servlet de Apache CXF

1. Crear la interfaz del servicio web, HolaMundo.java

 
package com.dosideas.cxf;
 
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
 
@WebService
public interface HolaMundo {
 
    String decirHola(String nombre);
 
    @WebResult(name="persona")
    Persona buscarPersona(@WebParam(name="legajo") long legajo);
}
 

La anotación @WebService de JAX-WS indica que esta clase será tratada como un Servicio Web. Es la única anotación obligatoria en la interfaz para Apache CXF. Sin embargo, pueden usarse otras anotaciones (como @WebParam, @WebResult y más) para configurar más detalladamente el servicio web que se generará. En la interfaz usamos las anotaciones @WebParam y @WebResult para darle un nombre particular a los elementos del parámetro y del resultado. Si no los indicamos, se generarán con valores predeterminados.

La clase Persona es un simple POJO que representa un objeto de dominio:

 
package com.dosideas.cxf;
 
public class Persona {
    private long legajo;
    private String nombre;
 
    //getter y setters a continuacion
    ...
}
 

2. Crear la implementación del servicio web, HolaMundoImpl.java

Creamos la implementación de nuestro servicio, que cumplirá con la interfaz HolaMundo.

 
package com.dosideas.cxf;
 
import javax.jws.WebService;
 
@WebService(endpointInterface = "com.dosideas.cxf.HolaMundo")
public class HolaMundoImpl implements HolaMundo {
 
    public String decirHola(String nombre) {
        return "Hola, " + nombre;
    }
 
    public Persona buscarPersona(long legajo) {
        Persona persona = new Persona();
        persona.setLegajo(legajo);
        persona.setNombre("Mock de persona para el legajo " + legajo);
        return persona;
    }
}
 

La anotacion @WebService(endpointInterface = "com.dosideas.cxf.HolaMundo") en esta clase le indica a Apache CXF cuál será la interfaz de este servicio web. Es la única anotación que se necesita agregar en la implementación.

3. Crear la configuración de Spring

Apache CXF se integra totalmente con Spring, y hace que la configuración del servicio web sea muy sencillo. En un archivo de Spring deberemos:

  1. Importar algunos recursos de Apache CXF.
  2. Declarar como un bean la clase implementación.
  3. Declarar el servicio web con un tag propio de Apache CXF, en donde indicaremos la dirección desde donde será accesible.

Llamaremos applicationContext.xml a este archivo de configuración, el cual queda muy sencillo:

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/
beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
 
    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
 
    <bean id="holaMundoImpl" class="com.dosideas.cxf.HolaMundoImpl"/>
 
    <jaxws:endpoint
    id="holaMundo"
    implementor="#holaMundoImpl"
    address="/HolaMundo" />
 
</beans>
 

4. Configurar el archivo web.xml

Nos queda el último paso, que será configurar el archivo web.xml. Allí deberemos realizar dos acciones:

  1. Configurar el listener de Spring para que levante el factory (o cualquier otro mécanismo de Spring)
  2. Configurar el servlet de Apache CXF que se encargará de exponer el servicio web.

El archivo web.xml queda entonces:

 
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
             org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
 
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>
      org.apache.cxf.transport.servlet.CXFServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
 
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>
 

El servlet CXFServlet de Apache CXF se encarga de recibir todas las peticiones a la aplicación web. Cuando accedamos a la raiz de nuestra aplicación web veremos un listado con todos los servicios web del módulo.

Desplegando el servicio web

¡Ya casi está todo listo! Nos queda empaquetar todos estos archivos dentro del módulo web (wAR) y desplegarlo en nuestro contenedor Web. Si usamos Tomcat o GlassFish (u otros "clásicos") podremos desplegar la aplicación sin más cambios. Para otros contenedores deberemos consultar la guía de configuración específica para servidores de aplicaciones (en general es cuestión de agregar configuración específica para cada servidor de aplicaciones).

Suponiendo que hayamos desplegado la aplicacion web en un Tomcat en el puerto 8084 bajo el contexto "cxf-demo" podemos abrir nuestro navegador preferido (Firefox, o sea) y escribir:

http://localhost:8084/cxf-demo

Veremos un listado con nuestro servicio web, sus dos operaciones y la URL del WSDL. ¡Mágico! A continuación veremos cómo crear un cliente de servicios web.

Construcción de un cliente de servicios web con CXF

La creación de clientes de servicios web con Apache CXF es muy sencilla, y se integra completamente con Spring.

Usando tags propios de CXF, podremos configurar el cliente como un bean más, e inyectarlo en cualquier parte de nuestra aplicación.

Deberemos contar con una interfaz Java que cumpla con la firma del servicio web. En este ejemplo, usaremos la misma clase HolaMundo.java como interfaz, pero podría ser otra interfaz (siempre y cuando cumpla con la firma).

A continuación entonces realizaremos dos pasos:

  1. Crear el archivo de configuración de Spring, applicationTest.xml
  2. Crear un test JUnit para probar el cliente

1. Crear el archivo de configuración de Spring

Lo primero será crear un archivo de configuración de Spring, que llamaremos applicationTest.xml, con un único bean que representa al cliente de nuestro servicio web. Apache CXF se encargará de realizar la conexión al servicio web, serializar y deserializar los datos y más.

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/
beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
 
    <!-- Este bean será el cliente del Web Service. Apache CXF generará un
         cliente que cumpla con la interfaz indicada y que accede al
         Web Service indicado en el atributo "address". Este bean luego
         puede inyectarse y utilizarse normalmente como cualquier otro objeto.
    -->
    <jaxws:client id="holaMundoCliente"
                  serviceClass="com.dosideas.cxf.HolaMundo"
                  address="http://localhost:8084/HolaMundo" />
</beans>
 

Como vemos, tenemos un bean holaMundoCliente el cual representa el servicio web. ¡Más facil imposible!

2. Crer un test JUnit para probar el cliente

Por último, crearemos un test JUnit para comprobar el correcto funcionamiento de nuestro cliente. Por supuesto, para ejecutar este test JUnit deberemos tener desplegado el servicio web que hicimos anteriormente.

 
package com.dosideas.cxf;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:com/dosideas/cxf/applicationTest.xml"})
public class ClienteHolaMundoTest {
 
    @Autowired
    private HolaMundo instance;
 
    @Test
    public void testDecirHola() {
        System.out.println("decirHola");
        String nombre = "Zim";
        String expResult = "Hola, " + nombre;
 
        String result = instance.decirHola(nombre);
 
        assertEquals(expResult, result);
    }
 
    @Test
    public void testBuscarPersona() {
        System.out.println("buscarPersona");
        long legajo = 29L;
 
        Persona result = instance.buscarPersona(legajo);
 
        assertNotNull(result);
        assertEquals(legajo, result.getLegajo());
        assertNotNull(result.getNombre());
        assertTrue(!result.getNombre().isEmpty());
    }
}
 

Conclusión

Apache CXF es un framework Java para la utilización de servicios web. Cuenta con una fuerte integración con Spring, por lo que es muy conveniente de facil de configurar para proyectos que usen este framework de aplicación.

Apache CXF es muy flexible y cuenta con muchísimas opciones para crear servicios web, partiendo desde código Java (como acabamos de ver), o desde un WSDL ya existente.

Para aprender más sobre Apache CXF pueden descargar este ejemplo a continuación, y leer la documentación de Apache CXF.

descargar el proyectoDescargar el proyecto de ejemplo

Pueden descargar el proyecto de ejemplo de Apache CXF, un proyecto de NetBeans IDE 6.5 ya configurado y con todas las librerías necesarias para compilar y ejecutar esta demo.

Compartir
  • Invitado

    Estos archivos de donde los saca?



  • Invitado

    Podrias publicar de favor la configuracion requerida para usar CXF con maven? o si es posible poner la demo como maven project?
    Saludos y Felicitaciones Excelente Articulo!!

  • Por mi parte no tengo mucha experiencia con Maven, no te puedo ayudar ahí. Sin embargo, no creo que haya mayores problemas: será cuestión de agregar el artifact de apache-cxf. Buscando rápido en google encuentro las siguientes dependencias:

    org.apache.cxf
    cxf-rt-frontend-jaxws
    2.0.10

    org.apache.cxf
    cxf-rt-transports-http
    2.0.10

    Más info en este post.

    Si lográs hacerlo funcionar con Maven, por favor compartilo!

  • Invitado

    Buenas,
    He seguido los pasos pero con la herramienta Rational Software Development Platform no reconoce los símbolos @ como @WebService o @WebResult.
    ¿Como se soluciona?
    Gracias.

  • Como va. No tengo experiencia con esa plataforma, pero si no te reconoce los "@" podría ser que no es compatible con Java SE 5 (que es un requerimiento para Apache CXF). Asegurate de estar usando esa versión del JDK.

  • HOla,

    Interesante artículo sobre Apache CXF.

    Simplemente comentar que existe una errata. A la hora de configurar el archivo de spring para el test, en la URL de invocación (address="http://localhost:8084/HolaMundo" />) falta a continuación de número de puerto la aplicación web donde está desplegado el servicio web, según el ejemplo esto es "cxf-demo".

    Por tanto URL quedaría:

    address="http://localhost:8084/cxf-demo/HolaMundo

    Enhorabuena por la web.

  • Invitado

    Hola, excelente ejemplo. Queria preguntarte que el ejemplo funciono muy bien en mi maquina local con win, pero al subirlo a desarrollo no me genera el wsdl, sera que hay q agregar alguna configuracion mas al apache-tomcat que esta instalado en ese entorno ?
    Saludos cordiales

  • sock_osg

    los archivos de configuracion de cxf para spring ya estan inckuidos en el jar de cxf, por lo que si este jar esta en tu classpath entonces ya deberian estar incluidos, de ahi que al hacer el import lo hace con classpath:META-INF......

  • Hola,

    El ejemplo no funciona con NetBeans 6.5.

    Al compilar el proyecto me da este error:

    wsgen-HolaMundoImpl:
    java.lang.NoSuchMethodError: com.sun.tools.apt.Main.process(Lcom/sun/mirror/apt/AnnotationProcessorFactory;[Ljava/lang/String;)I
    at com.sun.tools.ws.wscompile.WsgenTool.buildModel(WsgenTool.java:194)

    Un saludo.

  • websearch

    El tutorial es tan bueno , que mi profe lo usa para sus clases , pero no lo pudo correr correctamente.

  • sas

    hola, el tutorial esta muy bueno, mas bien nosé si nos podrías orientar un poco en el caso de implementarlo en dos PC´s .. el cliente por ejemplo en otra PC. saludos

  • [quote name="sas"]hola, el tutorial esta muy bueno, mas bien nosé si nos podrías orientar un poco en el caso de implementarlo en dos PC´s .. el cliente por ejemplo en otra PC. saludos[/quote]

    Para que el cliente consuma el servicio web funcionando en otro equipo, tenés que configurar el XML del cliente, la propiedad "address" de jaxws:client.

    Fijate en el XML del título "1. Crear el archivo de configuración de Spring", el atributo "address" dice "http://localhost:8084/HolaMundo". Tenés que cambiar ese valor por la dirección y puerto del equipo donde esté desplegado el web service.

  • sas

    Gracias, hice lo que me dijiste, lo cambie por la ip del otro equipo, gracias :) , no era tan complicado :D...}

  • Tavo

    Excelente tu articulo. Una consulta, actualmente estoy trabajando con XFire y tengo un ambiente armado donde en cada webservice uso el tag @CustomWebService, esto lo lee una libreria e interpreta esto como un webservice de XFire y lo expone. ¿Sabes alguna idea de cómo hacer para publicar un webservice hecho con CXF solo con anotaciones, sin configuraciones en XML (mas que nada del endpoint)?. Agradecido desde ya.

  • Héctor

    Muchas gracias por este tutorial.
    Gracias a ti, hoy he aprendido bastante

  • Remy t

    Hola, excelente articulo y como le hago con spring MVC??

  • gnu.ico

    gracias, yo uso eclipse y maven me sirvio de mucha ayuda

  • Joss

    Me gustaría montar un ambiente de desarrollo de aplicaciones WEB basado en Software, me gustaría montar un ambiente con: PostgreSQL, JBoss, Eclipse, Java, JPA, RichFaces, JUnit, pero no tengo idea de como instalar, configurar y posteriormente desarrollar. Alguna recomendación?

Deja tus comentarios

0

El nuevo Dos Ideas.

Nuevo logo, nuevo buscador, nueva portada, podcast mensual... ¡y muchas novedades más!

Más novedades en Dos Ideas

Los Comentarios.

Tihuilo
Soy nuevo en el desarrollo de software y he escuchado sobre el tema paro no se por donde iniciar, co...
abelastico1234
el paly station es mucho mejor que la psx tiene mas juegos ,mejores que los de la psx

Inspiración.

"Si tú tienes una manzana y yo tengo una manzana e intercambiamos las manzanas, entonces tanto tú como yo seguiremos teniendo una manzana cada uno. Pero si tú tienes una idea y yo tengo una idea, e intercambiamos las ideas, entonces ambos tendremos dos ideas"

Bernard Shaw