Create and publish a SOAP Webservice with CXF and Maven


We will see in this post how to create and publish a service with tomcat maven and CXF.

First, initialize the project with the Maven webapp archetype:

mvn archetype:create -DgroupId=com.test.ws.cxf -DartifactId=cxf-webapp -DarchetypeArtifactId=maven-archetype-webapp
cd ./cxf-webapp
mvn clean


Edit the pom.xml to include the following dependencies:

<dependency>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-rt-frontend-jaxws</artifactId>
 <version>2.3.1</version>
</dependency>
<dependency>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-rt-transports-http</artifactId>
 <version>2.3.1</version>
</dependency>

Create a WSDL, we will remain a classic and simple HelloWorld service:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://com.test.ws/hello/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="hello" targetNamespace="http://com.test.ws/hello/">
 <wsdl:types>
  <xsd:schema targetNamespace="http://com.test.ws/hello/">
   <xsd:element name="HelloWorld">
    <xsd:complexType>
      <xsd:sequence>
       <xsd:element name="in" type="xsd:string"/>
      </xsd:sequence>
     </xsd:complexType>
    </xsd:element>
    <xsd:element name="HelloWorldResponse">
     <xsd:complexType>
      <xsd:sequence>
       <xsd:element name="out" type="xsd:string"/>
      </xsd:sequence>
     </xsd:complexType>
    </xsd:element>
   </xsd:schema>
  </wsdl:types>
 <wsdl:message name="HelloWorldRequest">
  <wsdl:part element="tns:HelloWorld" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="HelloWorldResponse">
   <wsdl:part element="tns:HelloWorldResponse" name="parameters"/>
 </wsdl:message>
 <wsdl:portType name="hello">
  <wsdl:operation name="HelloWorld">
   <wsdl:input message="tns:HelloWorldRequest"/>
  <wsdl:output message="tns:HelloWorldResponse"/>
 </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="helloSOAP" type="tns:hello">
 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="HelloWorld">
 <soap:operation soapAction="http://com.test.ws/hello/HelloWorld"/>
 <wsdl:input>
  <soap:body use="literal"/>
 </wsdl:input>
 <wsdl:output>
  <soap:body use="literal"/> </wsdl:output>
 </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="hello">
  <wsdl:port binding="tns:helloSOAP" name="helloSOAP">
   <soap:address location="http://www.example.org/"/>
  </wsdl:port>
 </wsdl:service>
</wsdl:definitions>


Placer le WSDL dans WEB-INF/wsdl/hello.wsdl
A présent nous allons générer le code java grâce au plugin maven de CXF. Pour celà nous allons rajouter ceci au fichier pom :

Place the WSDL in WEB-INF/wsdl/hello.wsdl
Now we will generate the java code with the CXF maven plugin. For that, add the following to the pom.xml:


<plugins>
 <plugin>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-codegen-plugin</artifactId>
 <version>2.3.1</version>
 <executions>
  <execution>
   <id>generate-sources</id>
   <phase>generate-sources</phase>
   <configuration>
    <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>    
    <wsdlOptions>
     <wsdlOption>
      <wsdl>${basedir}/src/main/webapp/WEB-INF/wsdl/hello.wsdl</wsdl>
      <extraargs>
       <extraarg>-impl</extraarg>
       <extraarg>-wsdlLocation</extraarg>
       <extraarg>/WEB-INF/wsdl/hello.wsdl</extraarg>
      </extraargs>
     </wsdlOption>
    </wsdlOptions>
   </configuration>
   <goals>
    <goal>wsdl2java</goal>
   </goals>
  </execution>
 </executions>
 </plugin>
</plugins>

And run this :

mvn generate-sources

Generated code is now in /target/generated/cxf.
Copy the generated code to your sources directory (or add /target/generated/cxf to your classpath), by convention /src/main/java, and make modification as you wich in HelloImpl.java. It is in this classe that the service is implemented.

It remains only to publish the service. For this CXF provide two alternatives, but the second does not seem operational.
Here is how your web.xml must be filled :

<!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/beans.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> </servlet>
 <servlet-mapping>
 <servlet-name>CXFServlet</servlet-name>
 <url-pattern>/services/*</url-pattern>
 </servlet-mapping>
</web-app>

Finally we just have to declare the services in spring (CXF includes dependencies to spring, no additional library has to be declared in maven). Create the file WEB-INF/beans.xml:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.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="helloBean" implementor="ws.test.com.hello.HelloImpl" address="/helloService" endpointName="e:helloSOAP" serviceName="e:hello" xmlns:e="http://com.test.ws/hello/" wsdlLocation="WEB-INF/wsdl/hello.wsdl"/
</beans>

rest to package :

mvn package

The war is ready to be deployed in tomcat.

have fun ;)

Commentaires

Posts les plus consultés de ce blog

How-to : Les web services en Java 6

Annotations personnalisées résolues au runtime