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

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/