Enterprise Integration Zone is brought to you in partnership with:

Steve Daskam is currently a Senior Java Developer and Tech Lead at hotels.com Steve has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

Web Services with Mule, CXF, and Spring

07.04.2008
| 70754 views |
  • submit to reddit

Since it seems like everything is going the way of SOA and Web Services these days, it's always nice to have some practical examples of how to quickly get a service up and running. And since many of the frameworks such as Mule and CXF are fairly new to a lot of us, and the documentation tends to take a backseat to the development effort, the more practical examples that are available, the better.

This article is intended to be a quick tutorial on how to get a web service up and running using the combination of a spring-based service (POJO) with CXF and the Mule Enterprise Service Bus.

Getting Started

To run the code associated with this article, you will need to download the latest version of Mule from:
http://mule.mulesource.org/display/MULE/Download.

At this time, the latest stable community version is 2.01. Follow the instructions on the website to install Mule.

The Code

For this example, we are going to be creating a Product Catalog service, where users can get a list of the products that we sell, and can also get the details for specific products. We are going to use a code-first approach for this service using JAX-WS annotations.

First, we will need to create several classes:
1) the interface for our service
2) the implementation class for our service
3) our product bean

The Interface

The code for the interface is shown below. Note the annotations that are used. The @WebService annotation is used to denote that this is a web service (pretty self-explanatory), @WebResult is used to specify that our output be wrapped in a tag with the given name, and @WebParam is used to give a name to our input parameter, which makes things more readable for SOAP clients. The rest of the code is just our standard java interface.

package example.catalog;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import java.util.Collection;
import java.util.List;

@WebService
public interface ProductCatalogService {

@WebResult(name="item")
public List<String> listProducts();

@WebResult(name="product")
public Product getProductDetail(@WebParam(name="productId") String productId);

}


The Implementation

The implementation class is just a regular java class that implements our interface, and uses the single @WebService annotation. Using this annotation, you can specify the name and endpoint interface to be used for the service.

package example.catalog;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebService(endpointInterface = "example.catalog.ProductCatalogService",
serviceName = "ProductCatalogService")
public class ProductCatalogServiceImpl implements ProductCatalogService {
Map<String, Product> productMap = new HashMap<String, Product>();

public ProductCatalogServiceImpl() {
// Load some products
Product product = new Product("SW123", "Square Widget", 10, 10);
productMap.put(product.getId(), product);
product = new Product("RW456", "Round Widget", 5, 5);
productMap.put(product.getId(), product);
}

public List<String> listProducts() {
List<String> productListing = new ArrayList<String>();

Collection<Product> products = productMap.values();
for (Product p : products) {
productListing.add(p.getId() + " - " + p.getDescription());
}

return productListing;
}

public Product getProductDetail(String productId) {
Product product = null;
product = productMap.get(productId);
return product;
}

}


The Product Bean

The Product bean is just a standard java bean which must follow standard conventions for everything to work correctly. It must implement the Serializable interface, must have a default constructor, and must have both getters AND setters. This bean will be automatically marshalled to XML using JAXB and will be returned in the SOAP response.

package example.catalog;

import java.io.Serializable;

public class Product implements Serializable {
private String id;
private String description;
private int width;
private int height;

public Product() {
}

public Product(String id, String description, int width, int height) {
this.id = id;
this.description = description;
this.width = width;
this.height = height;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

}
Legacy
Article Resources: 
Published at DZone with permission of its author, Steve Daskam.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Jason Whaley replied on Fri, 2008/07/04 - 4:28pm

Decent article. I work day to day with a suite of web services implemented with the exact same stack (but using a wsdl first approach).  It, for the most part, gets the job done, although there was more legwork involved than what you've described due to the fact a wsdl first approach was selected.

However, I think this article lacks in showing the real strength of the mule esb, which is applying transformations, multiple/chainable routing, and abstracting the protocol away from the implementation (e.g. seamlessly going from a web service call over HTTP to a JMS queue, yet your code never knows that's happening), and in general sitting in front or behind the web service doing such work and not being solely there for containing the web service.

Richard Yang replied on Thu, 2008/09/18 - 11:28am

Excellent article. The author covered everything what he said at the beginning and mentioned that there were more to explore at the conclusion.  Will someone cover the advanced/other features?

Hat off to Steve Haskam.

 

Balu Gulla replied on Sun, 2009/10/18 - 10:35pm

 Awesome.

I'm learing mule, I impressed with your blog, If you any mule related blogs please let me know. 

Thanks,

Balu

Jammy Chen replied on Mon, 2012/12/03 - 10:24am

Really nice article. Recently I am learning that use CXF and Spring to publish web service. I just want to share another same excellent article  http://www.asjava.com/web-services/cxf-spring-support/ 

Ga Sita replied on Thu, 2011/05/12 - 9:14pm

Nice article, Anyone has any experience for consuming a SAP webservice and transforming it to different form to another endpoint in mule? thanks.

David Mccullough replied on Wed, 2013/11/06 - 11:13am

I have a couple of questions (new to mule)

Is the  catalogservice-config.xml a separate file from the *.mflow?

Is there an easy way to test this in studio?

David Mccullough replied on Wed, 2013/11/06 - 11:15am

I have a couple of questions (new to mule)

Is the  catalogservice-config.xml a separate file from the *.mflow?

Is there an easy way to test this in studio?


I am having problems with the following in my *.mflow file compiling in Mulestudio.

<spring:beans><spring:import resource="catalogContext.xml"/></spring:beans>

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.