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:

<br />
package test;</p>
<p>import javax.jws.WebService;</p>
<p>@WebService<br />
public interface SayHello {</p>
<p>	  String sayHello(String name);<br />
}<br />

Y su implementación:

<br />
package test;</p>
<p>import javax.jws.WebService;</p>
<p>@WebService(endpointInterface=&amp;quot;test.SayHello&amp;quot;<br />
)<br />
public class SayHelloImpl implements SayHello {</p>
<p>	public String sayHello(String name) {<br />
		return &amp;quot;Hello &amp;quot; + name + &amp;quot;!&amp;quot;;<br />
	}</p>
<p>}<br />

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:

<br />
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br />
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;<br />
	xmlns:jaxws=&quot;http://cxf.apache.org/jaxws&quot;<br />
	xsi:schemaLocation=&quot;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&quot;&gt;</p>
<p>	&lt;import resource=&quot;classpath:META-INF/cxf/cxf.xml&quot; /&gt;<br />
	&lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-soap.xml&quot; /&gt;<br />
	&lt;import resource=&quot;classpath:META-INF/cxf/cxf-<br />
servlet.xml&quot; /&gt;</p>
<p>	&lt;jaxws:endpoint id=&quot;sayHello&quot; implementor=&quot;test.SayHelloImpl&quot; address=&quot;/SayHello&quot;&gt;<br />
		&lt;jaxws:features&gt;<br />
			&lt;bean class=&quot;org.apache.cxf.feature.LoggingFeature&quot; /&gt;<br />
		&lt;/jaxws:features&gt;<br />
	&lt;/jaxws:endpoint&gt;</p>
<p>&lt;/beans&gt;<br />

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:

<br />
&lt;bean id=&quot;sayHelloService&quot; class=&quot;test.SayHelloImpl&quot; /&gt;</p>
<p>&lt;jaxws:endpoint id=&quot;sayHello&quot; implementor=&quot;#sayHelloService&quot; address=&quot;/SayHello&quot;&gt;<br />
	&lt;jaxws:features&gt;<br />
		&lt;bean class=&quot;org.apache.cxf.feature.LoggingFeature&quot; /&gt;<br />
	&lt;/jaxws:features&gt;<br />
&lt;/jaxws:endpoint&gt;<br />

WEB-INF/web.xml contiene la configuración para levantar el contexto de Spring y el servlet de CXF

<br />
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br />
&lt;!DOCTYPE web-app PUBLIC<br />
 &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot;<br />
 &quot;http://java.sun.com/dtd/web-app_2_3.dtd&quot; &gt;</p>
<p>&lt;web-app&gt;<br />
	&lt;context-param&gt;<br />
		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;<br />
		&lt;param-value&gt;WEB-INF/application-config.xml&lt;/param-value&gt;<br />
	&lt;/context-param&gt;</p>
<p>	&lt;listener&gt;<br />
		&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br />
	&lt;/listener&gt;</p>
<p>	&lt;servlet&gt;<br />
		&lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;<br />
		&lt;display-name&gt;CXF Servlet&lt;/display-name&gt;<br />
		&lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt;<br />
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
	&lt;/servlet&gt;</p>
<p>	&lt;servlet-mapping&gt;<br />
		&lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;<br />
		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
	&lt;/servlet-mapping&gt;<br />
&lt;/web-app&gt;<br />

Para el manejo de dependencias utilizaremos Maven, y las dependencias incluídas en el POM del proyecto son las siguientes:

<br />
&lt;dependencies&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;<br />
		&lt;artifactId&gt;cxf-rt-core&lt;/artifactId&gt;<br />
		&lt;version&gt;2.1&lt;/version&gt;<br />
	&lt;/dependency&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;<br />
		&lt;artifactId&gt;cxf-rt-frontend-simple&lt;/artifactId&gt;<br />
		&lt;version&gt;2.1&lt;/version&gt;<br />
	&lt;/dependency&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;<br />
		&lt;artifactId&gt;cxf-rt-frontend-jaxws&lt;/artifactId&gt;<br />
		&lt;version&gt;2.1&lt;/version&gt;<br />
	&lt;/dependency&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;<br />
		&lt;artifactId&gt;cxf-rt-transports-local&lt;/artifactId&gt;<br />
		&lt;version&gt;2.1&lt;/version&gt;<br />
	&lt;/dependency&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;<br />
		&lt;artifactId&gt;cxf-rt-transports-http&lt;/artifactId&gt;<br />
		&lt;version&gt;2.1&lt;/version&gt;<br />
	&lt;/dependency&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;<br />
		&lt;artifactId&gt;cxf-common-utilities&lt;/artifactId&gt;<br />
		&lt;version&gt;2.1&lt;/version&gt;<br />
	&lt;/dependency&gt;<br />
	&lt;dependency&gt;<br />
		&lt;groupId&gt;junit&lt;/groupId&gt;<br />
		&lt;artifactId&gt;junit&lt;/artifactId&gt;<br />
		&lt;version&gt;4.4&lt;/version&gt;<br />
		&lt;scope&gt;test&lt;/scope&gt;<br />
	&lt;/dependency&gt;<br />
&lt;/dependencies&gt;<br />

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/