Web services code-first y contract-first (de Lijin’s Localhost)
Una colección de links con blog posts muy completos acerca de creación de web services code-first y contract-first utilizando CXF.
Code-first
1. Creating Web services using Apache CXF (Part 1) : The Basics.
2. Creating Web services using Apache CXF (Part 2) : Development.
3. Creating Web services using Apache CXF (Part 3) : Configuration.
4. Creating Web services using Apache CXF (Part 4): Testing.
Contract-first
1. Creating “Contract First” – Web Services using CXF (Top Down Approach) Part 1: Creating XSDs.
2. Creating Web Services using CXF (Contract first Approach) Part 2 : WSDL Creation.
Web services con Spring framework y CXF
Implementar y exponer web services utilizando Spring framework ha sido una tarea recurrente en mi día a día. En este post describiré qué y cómo configurar para tener un web service funcionando con Spring y CXF sobre Tomcat 6.
En este ejemplo tendremos un enfoque code-first, es decir, que definiremos los servicios a exponer en nuestras clases Java, para generar el WSDL a partir de éstas.
Con toda la originialidad del mundo, haremos un Hello world. La intefaz Java del servicio es la siguiente:
package test;
import javax.jws.WebService;
@WebService
public interface SayHello {
String sayHello(String name);
}
Y su implementación:
package test;
import javax.jws.WebService;
@WebService(endpointInterface="test.SayHello")
public class SayHelloImpl implements SayHello {
public String sayHello(String name) {
return "Hello " + name + "!";
}
}
Ya no necesitaremos más código, el resto es configuración. Bajo WEB-INF tenemos un XML de Spring llamado application-config.xml, con el siguiente contenido:
<?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" /> <jaxws:endpoint id="sayHello" implementor="test.SayHelloImpl" address="/SayHello"> <jaxws:features> <bean class="org.apache.cxf.feature.LoggingFeature" /> </jaxws:features> </jaxws:endpoint> </beans>
El elemento jaxws:endpoint esconde toda la magia, generando la definición del web service a partir de una clase. También se puede referenciar un bean de spring, poniendo el nombre en el implementor con el formato "#REF_BEAN_NAME", de la siguiente forma:
<bean id="sayHelloService" class="test.SayHelloImpl" /> <jaxws:endpoint id="sayHello" implementor="#sayHelloService" address="/SayHello"> <jaxws:features> <bean class="org.apache.cxf.feature.LoggingFeature" /> </jaxws:features> </jaxws:endpoint>
WEB-INF/web.xml contiene la configuración para levantar el contexto de Spring y el servlet de CXF
<?xml version="1.0" encoding="UTF-8"?> <!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> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/application-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <display-name>CXF Servlet</display-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> </web-app>
Para el manejo de dependencias utilizaremos Maven, y las dependencias incluídas en el POM del proyecto son las siguientes:
<dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-core</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-simple</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-local</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-common-utilities</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> </dependencies>
Para armar el WAR hacemos "mvn package" en la línea de comandos, posicionados en la raíz del proyecto. Esto generará un archivo target/ws-test.war, el cual copiaremos a la carpeta webapps de Tomcat. Luego de iniciar el tomcat, el WSDL del web service quedará disponible en http://localhost:8080/ws-test/SayHello?wsdl
La estructura final del proyecto es la siguiente:

Estructura del ejemplo
El proyecto de ejemplo se puede bajar de aquí.
Referencias:
http://ralf.schaeftlein.de/2008/05/04/apache-cxf-21-with-spring-2-maven-2-and-eclipse-wtp/
http://cxf.apache.org/