Spring Web Services: Implementing a Web Service
In the previous post, I introduced the design goals behind the Spring Web Services SOAP framework. In this post, I describe how one would go about implementing a Web service with Spring-WS. Please note that any code shown in this post is non-final, and only reflects the current design we have.
Before you implement your service, there are some design choices you need to make. These are important choices, but you can reuse these for every service.
How many classes?
First, there is the choice whether you want to implement a service endpoint in a single class, or in separate classes. Traditionally, Web services are just single classes, with every method representing an operation. This can result in large classes, and thus code smell. Within Spring-WS, there is the option to implement a service operation as separate class, just as you would implement a single Controller class when using a Web UI framework such as Spring-MVC. If you prefer to use a single class, however, that is also possible, but we will cover the single-class case in this post.
Message or payload?
Within a service endpoint, you have to choose whether you are interested in the complete message, or just the contents of the message body (i.e. the message payload). If you want the complete message, you implement the MessageEndpoint interface, which contains just one method:
SOAPMessage invoke(SOAPMessage request) throws Exception;
The SOAPMessage used here is the standard, SAAJ javax.xml.soap.SOAPMessage.
However, it is much more likely that you are interested in the message payload, because that contains the interesting bits.
If you want the message payload, you implement the Spring-WS interface PayloadEndpoint, which also contains one method:
Source invoke(Source request) throws Exception;
The Source used here is a javax.xml.transform.Source, a XML input abstraction. The PayloadEndpoint interface has convenience subclasses which allow you to use DOM, SAX, or StAX directly1
Within your endpoint, you read the XML, invoke a few business methods on your middle tier, and formulate a reply, if desired. Presto!
XML Marshalling?
Of course, you can use Object-XML mapping in your endpoint if you want to, making the handling of XML somewhat easier. We’ll cover the O/X Mapping support of Spring-WS in a future post, but suffice it to say that Spring-WS offers an abstraction which makes it easier to switch from one OXM implementation to another. Also, the exceptions thrown by these marshalling frameworks are all converted to runtime exceptions, and unified to a single hierarchy, just like in Spring’s data access and ORM support.
When the endpoint is done, you need to decide how it is mapped to a request. This topic is also reserved for a future post, but basically, all standard mapping techniques (URL-based, SOAPAction-based, and message-based), are supported. You can even write your own mapping logic if nothing suits you.
<hr/>
1 - Both MessageEndpoint and PayloadEndpoint can be compared with JAX-WS, which defines the Provider interface. By setting the enumerated value for a @ServiceMode annotation on the generic Provider, you can accomplish the same thing, though it’s a bit too Java 5-heavy for my taste.
October 30th, 2005 at 20:00
[...] The Ancient Art of Programming ยป Spring Web Services: Implementing a Web Service Spring Web Services: Implementing a Web Service (tags: webservices spring) [...]
October 31st, 2005 at 16:34
[...] Spring is going Webservices! Or a bit more specific, Spring is going SOAP. Arjen Poutsma has sent this message to the world during the last NL-JUG J-Fall conference. On his blog you can find the nitty gritty details. [...]
October 31st, 2005 at 22:45
I’m extremely excited about this project. I am using Spring heavily for all applications at my company, we are now exposeing a set of webservice interfaces for a 3rd party. Even with JAX RPC there is considerable pain. I really like the direction XFire (Codehaus) is taking with their stack. I hope the Spring group leverages some of their approaches.