Spring-WS
Took a look at Spring-WS and came up with a quick example service to describe its use. I decided to build an 'echo' service. Send in a text and it will echo that back with a date and time appended to the text.
After building the application I saw that Spring-WS comes with a sample echo service application. Oh well. Since I put in the effort here is the article on it.
Spring-WS encourages document based web services. As you know there are mainly two types of web services:
In the document based approach you no longer think of operations (their parameters and return types). You decide on what XML document you want to send in as input and what XML document you want to return from your web service as a response.
Spring-WS encourages a more practical approach to designing document based web services. Rather than think WSDL, it pushes you to think XSD (or the document schema) and then Spring-WS can auto-generate the WSDL from the schema.
Lets break it up into simpler steps:
Lets see the echo service in action. You will notice that I do not create any WSDL document throughout this article.
BusinessCase:
Echo service takes in an XML request document and returns an XML document with a response. The response contains the text that was sent in, appended with a timestamp.
RequestXML Sample:
The schema XSD file for this can be found in the WEB-INF folder of the application (echo.xsd).
ResponseXML Sample:
The schema XSD file for this can be found in the WEB-INF folder of the application (echo.xsd).
If you inspect the SOAP request and response you will see that this XML is whats inside the SOAP body. This is precisely what is document based web services.
EchoService Implementation:
Here is the echo service Java interface and its related implementation. As you can see this is a simple POJO.
Nowthe Spring-WS stuff:
Here is the web.xml for the sake of clarity.
Only thing to note in the web.xml is the Spring-WS servlet.
Next is the all important Spring bean configuration XML.
This is a simple class. Important point to note is that it extends 'AbstractJDomPayloadEndpoint'. The 'AbstractJDomPayloadEndpoint' class is ahelper that gives you the XML payload as a JDom object. There are similar classes built for SAX, Stax and others. Most of the code above is reading the request XML using JDOM API and parsing the data out so that we may provide it to our echo service for consumption.
Finally I build a response XML document to return and thats it.
Download the sample Application:
Click here to download the jar file containing the application. The application is built using Maven. If you do not have Maven please install it. Once Maven is installed run the following commands:
While I could not find a roadmap for Spring-WS, depending on the features it starts supporting this could become a very suitable candidate for web service integration projects. Sure folks will say where is WS-Transactions and all of that, but tell me how many others implement that. I think if Spring-WS grows to support 90% of what folks need in integration projects then it will suffice.
After building the application I saw that Spring-WS comes with a sample echo service application. Oh well. Since I put in the effort here is the article on it.
Spring-WS encourages document based web services. As you know there are mainly two types of web services:
- RPC based.
- Document based.
In the document based approach you no longer think of operations (their parameters and return types). You decide on what XML document you want to send in as input and what XML document you want to return from your web service as a response.
Spring-WS encourages a more practical approach to designing document based web services. Rather than think WSDL, it pushes you to think XSD (or the document schema) and then Spring-WS can auto-generate the WSDL from the schema.
Lets break it up into simpler steps:
- Create your XML schema (.xsd file). Inside the schema you will create your request messages and response messages. Bring up your favourite schema edit or to create the schema or write sample request and response XML and then reverse-engineer the schema (check if your tool supports it).
- You have shifted the focus onto the document (or the XML). Now use Spring-WS to point to the XSD and set up a few Spring managed beans and soon you have the web service ready. No WSDL was ever written.
Lets see the echo service in action. You will notice that I do not create any WSDL document throughout this article.
BusinessCase:
Echo service takes in an XML request document and returns an XML document with a response. The response contains the text that was sent in, appended with a timestamp.
RequestXML Sample:
| <ec:EchoRequest> <ec::Echo> <ec:Name>Mathew</ec:Name> </ec:Echo> </ec:EchoRequest> |
The schema XSD file for this can be found in the WEB-INF folder of the application (echo.xsd).
ResponseXML Sample:
| <ec:EchoResponse> <ec:EchoResponse> <ec:Message>echoback: name Mathew received on 05-06-2007 06:42:08PM</ec:Message> </ec:EchoResponse> </ec:EchoResponse> |
The schema XSD file for this can be found in the WEB-INF folder of the application (echo.xsd).
If you inspect the SOAP request and response you will see that this XML is whats inside the SOAP body. This is precisely what is document based web services.
EchoService Implementation:
Here is the echo service Java interface and its related implementation. As you can see this is a simple POJO.
| package echo.service; public interface EchoService { public String echo(java.lang.Stringname); } |
| package echo.service; import java.text.SimpleDateFormat; import java.util.Calendar; public class EchoServiceImpl implements EchoService { public String echo(String name) { if (name== null || name.trim().length() == 0) { return "echo back: -please provide aname-"; } SimpleDateFormat dtfmt = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a"); return"echo back: name " + name + " received on " +dtfmt.format(Calendar.getInstance().getTime()); } } |
Nowthe Spring-WS stuff:
Here is the web.xml for the sake of clarity.
| <?xml version="1.0"encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee ">java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>Echo WebService Application</display-name> <servlet> <servlet-name>spring-ws</servlet-name> <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>spring-ws</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> |
Only thing to note in the web.xml is the Spring-WS servlet.
Next is the all important Spring bean configuration XML.
| <?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans ">www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="echoEndpoint"class="echo.endpoint.EchoEndpoint"> <property name="echoService"><refbean="echoService"/></property> </bean> <bean id="echoService"class="echo.service.EchoServiceImpl"/> <beanclass="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping"> <property name="mappings"> <props> <propkey="{http://www.averconsulting.com/echo/schemas}EchoRequest" >echoEndpoint</prop> </props> </property> <property name="interceptors"> <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" /> </property> </bean> <bean id="echo"class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition"> <property name="builder"> <bean class="org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder"> <property name="schema" value="/WEB-INF/echo.xsd"/> <property name="portTypeName" value="Echo"/> <property name="locationUri"value="http://localhost:9090/echoservice/"/> </bean> </property> </bean> </beans> |
- Registered the 'echoService' implementation bean.
- Registered an endpoint class named 'echoEndpoint'. The endpoint is the class that receives the incoming web servicerequest.
- The endpoint receives the XML document. You parse the XML data and then call our echo service implementation bean.
- The bean 'PayloadRootQNameEndpointMapping'is what maps the incoming request to the endpoint class. Here we set up one mapping. Anytime we see a 'EchoRequest' tag with the specified namespace we direct it to our endpoint class.
- The 'XsdBasedSoap11Wsdl4jDefinitionBuilder'class is what does the magic of converting the schema XSD to a WSDL document for outside consumption. Based on simple naming conventions in the schema (like XXRequest and XXResponse) the bean can generate a WSDL. This rounds up the 'thinking in XSD for document web services' implementation approach. Once deployed the WSDL is availableat http://localhost:9090/echoservice/echo.wsdl.
| package echo.endpoint; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; import org.jdom.output.XMLOutputter; import org.jdom.xpath.XPath; importorg.springframework.ws.server.endpoint.AbstractJDomPayloadEndpoint; import echo.service.EchoService; public class EchoEndpoint extends AbstractJDomPayloadEndpoint{ private EchoService echoService; public void setEchoService(EchoServiceechoService) { this.echoService = echoService; } protected Element invokeInternal(Elementrequest) throws Exception { // ok nowwe have the XML document from the web service request // letssystem.out the XML so we can see it on the console (log4j // latter) System.out.println("XML Doc >> "); XMLOutputter xmlOutputter = new XMLOutputter(); xmlOutputter.output(request, System.out); // I amusing JDOM for my example....feel free to process the XML in //whatever way you best deem right (jaxb, castor, sax, etc.) // somejdom stuff to read the document Namespacenamespace = Namespace.getNamespace("ec", "http://www.averconsulting.com/echo/schemas"); XPathnameExpression = XPath.newInstance("//ec:Name"); nameExpression.addNamespace(namespace); // letscall a backend service to process the contents of the XML //document Stringname = nameExpression.valueOf(request); String msg =echoService.echo(name); // buildthe response XML with JDOM NamespaceechoNamespace = Namespace.getNamespace("ec", "http://www.averconsulting.com/echo/schemas"); Elementroot = new Element("EchoResponse", echoNamespace); ElementechoResponse = new Element("EchoResponse", echoNamespace); root.addContent(echoResponse); Elementmessage = new Element("Message", echoNamespace); echoResponse.addContent(message); message.setText(msg); Documentdoc = new Document(root); // returnresponse XML System.out.println(); System.out.println("XML Response Doc >> "); xmlOutputter.output(doc, System.out); returndoc.getRootElement(); } } |
This is a simple class. Important point to note is that it extends 'AbstractJDomPayloadEndpoint'. The 'AbstractJDomPayloadEndpoint' class is ahelper that gives you the XML payload as a JDom object. There are similar classes built for SAX, Stax and others. Most of the code above is reading the request XML using JDOM API and parsing the data out so that we may provide it to our echo service for consumption.
Finally I build a response XML document to return and thats it.
Download the sample Application:
Click here to download the jar file containing the application. The application is built using Maven. If you do not have Maven please install it. Once Maven is installed run the following commands:
- mvn package (this will generate the web service war file in the target folder).
- mvn jetty:run (this will bring up Jetty and you can access the wsdl at http://localhost:9090/echoservice/echo.wsdl.
- Finally use some web service accessing tool like the eclipse plug-in soapUI to invoke the web service.
While I could not find a roadmap for Spring-WS, depending on the features it starts supporting this could become a very suitable candidate for web service integration projects. Sure folks will say where is WS-Transactions and all of that, but tell me how many others implement that. I think if Spring-WS grows to support 90% of what folks need in integration projects then it will suffice.






Nice post!
With regard to content transformation: did you see the PayloadTransformingInterceptor?
http://static.springframework.org/spring-ws/site/apidocs/org/springframework/ws/server/endpoint/interceptor/PayloadTransformingInterceptor.html
Reply to this
nice! but do not stop, continue please. deep-into-
Reply to this
Great article. It was very precise and gave a good step-by-step approach to building document based web services with Spring WS.
Reply to this
nice post, helps a lot - thanks.
Reply to this
very concise explanation.Keep posting!..thnx
Reply to this
Very nice, first maven project in a tutorial that actually worked first try for me. would like to see a sample of functional client code or a link to how to use soapUI. I'm very new to spring-ws so the little things tripping me up are the worst. Thanks for this great tutorial!
Reply to this
Great article. It was very useful. Thank you.
Reply to this
thanks Mathew,
g8 Article on Spring-WS.
but, it was written in 2007. is there any improvements or new features had been added in the past 2 years?
if the above process had been automatted using Eclipse plug-ins it would be greate helpful. please post related links.
thanks,
McCatney
Reply to this
Yes, great post. Near the end you say: "Spring-WS supports the WS-I basic profile and WS-Security. I hope to look at the WS-Security support sometime soon." I would love to see an example showing spring ws with ssl using x509 certs. Either wssj or xwss.
Reply to this
Bob, I do want to try them out... the last time I tried it with xfire (i think) i got a headache.
Reply to this
Great post ... did not find anything as simple as this anywhr.. great wrk
Reply to this