I introduced Apache CXF in my last post. I planned on writing some good examples of my own on using the framework, but to be honest I would struggle to beat the time and depth of examples the CXF download provides in its samples directory(Apache CXF Version 3)
Instead I decided it would be more interesting to provide commentary to some of these examples, including –
Thanks to the Apache CXF developers for providing this software, and these great examples. All code contained in this post is released by Apache under the Apache License.
WSDL First Demo
There are two approaches to building web services – contract first and contract last. Contract first is where the wsdl is defined first, and contract last is where the wsdl is defined last. Apache CXF supports both forms of development.
This example is found under apache-cxf\samples\wsdl_first, and is an examples of a contract first application
WSDL Contract
The wsdl follows the standard structure –
It defines 2 operations –
Finally the service defines 2 endpoints, one for standalone, and one for a tomcat deployment –
[sourcecode lang=”xml”] <wsdl:service name="CustomerServiceService">Web Service Implementation – CustomerServiceImpl
The CustomerServiceImpl implements the CustomerService interface, which is created through the maven task – wsdl2java
[sourcecode lang=”java”] public class CustomerServiceImpl implements CustomerService { // The WebServiceContext can be used to retrieve special attributes like the
// user principal. Normally it is not needed
@Resource
WebServiceContext wsContext;
public List&lt;Customer&gt; getCustomersByName(String name) throws NoSuchCustomerException {
// …
}
public void updateCustomer(Customer customer) {
// …
}
}
[/sourcecode]
The interface itself looks like, where you can see the autogenerated JAX-WS annotations –
[sourcecode lang=”java”] @WebService(targetNamespace = &quot;http://customerservice.example.com/&quot;, name = &quot;CustomerService&quot;) @Oneway
@RequestWrapper(localName = &quot;updateCustomer&quot;,
targetNamespace = &quot;http://customerservice.example.com/&quot;,
className = &quot;com.example.customerservice.UpdateCustomer&quot;)
@WebMethod
public void updateCustomer(@WebParam(name = &quot;customer&quot;, targetNamespace = &quot;&quot;)
com.example.customerservice.Customer customer
);
@WebResult(name = &quot;return&quot;, targetNamespace = &quot;&quot;)
@RequestWrapper(localName = &quot;getCustomersByName&quot;,
targetNamespace = &quot;http://customerservice.example.com/&quot;,
className = &quot;com.example.customerservice.GetCustomersByName&quot;)
@WebMethod
@ResponseWrapper(localName = &quot;getCustomersByNameResponse&quot;,
targetNamespace = &quot;http://customerservice.example.com/&quot;,
className = &quot;com.example.customerservice.GetCustomersByNameResponse&quot;)
public java.util.List&lt;com.example.customerservice.Customer&gt; getCustomersByName(
@WebParam(name = &quot;name&quot;, targetNamespace = &quot;&quot;) java.lang.String name
) throws NoSuchCustomerException;
}
[/sourcecode]
CXFServlet
web.xml defines the CXFServlet –
[sourcecode lang=”xml”] <servlet>The CXFServlet adds a Spring context, which is defined through a file called cxf.xml. This defines the end point, this is the default name and could be changed through web.xml configuration –
[sourcecode lang=”xml”] <!– comment this bean to disable schema validation in the client –>Server Implementation
The intention of this tutorial is to deploy to JBoss Fuse, but I thought it was interesting to look at the different options offered in this example. The first uses JAX-WS or Spring
Spring – Injection of endpoint into jaxws server –
[sourcecode lang=”xml”] <!– HTTP Endpoint –>JAX-WS – The Endpoint is coded directly –
[sourcecode lang=”java”] CustomerService implementor = new CustomerServiceImpl();// Adding logging for incoming and outgoing messages
ep.getServer().getEndpoint().getInInterceptors().add(new LoggingInInterceptor());
ep.getServer().getEndpoint().getOutInterceptors().add(new LoggingOutInterceptor());
[/sourcecode]
Build (pom.xml)
The core part of the pom is the cxf-codegen-plugin. This plugin takes the wsdl and generates the java source code through its wsdl2java goal –
[sourcecode lang=”xml”] <plugin>Key points –
Putting it all together
The tutorial instructions are quite simple –
mvn clean install (builds the demo and creates a WAR file for optional Tomcat deployment)
mvn -Pserver (from one command line window — only if using embedded Jetty)
mvn -Pclient (from a second command line window)
Or change the CustomerService.wsdl, and rerun maven. Then copy the wsdl_first.war to the deploy directory of tomcat. You can test the installation by running –
http://localhost:8080/wsdl_first/services/CustomerServicePort?wsdl
You can then test this installation using a tool like SOAPUI, and sending a message like –
[sourcecode lang=”xml”] <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://customerservice.example.com/">Or to update the customer –
[sourcecode lang=”xml”] <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://customerservice.example.com/">The tomcat log shows the interaction
update request was received Customer was updated