I played around with the Spring WebService library and this is a summary of what I did or what you need to take care of while implementing your own web service.
My toy project Whois-WS is about domain WHOIS information. You can ask the service about a domain name and it will return basic information about the domain, such as the domain name, connection status and responsible whois server.
To begin with, use the tutorial to start. You'll learn pretty fast with it. Really great tutorial and covers all the stuff to get warm with the topic.
1.) Take time to think about what your service does before you start developing your own service. Take care to not make your Business Object Model (BOM) too complex.
My example is going to be a password-secured WHOIS Service, which provides information about a domain name.
2.) Start with a simple "Hello World" example, use simple String input and String output. When you've got that running, go on and make your BOM with more complex types.
Simple model
3.) Immediately document your BOM with XML Schema Annotations. Give examples for your values. That will be visible in the dynamically generated WSDL.
XML Schema Documentation
4.) The .wsdl file is always reachable at "/yourwebapp/foo.wsdl", with foo being the Bean ID of your WsdlDefinition.
Bean Id is service name
5.) Use JAXB2 + Maven + Spring-WS. Besides spring-ws artifacts and junit, you'll need the following dependencies:
view plaincopy to clipboardprint?
1.
2. com.sun.xml.messaging.saaj
3. saaj-impl
4. 1.3
5. runtime
6.
7.
8. javax.xml.bind
9. jaxb-api
10. 2.0
11.
12.
13. com.sun.xml.bind
14. jaxb-impl
15. 2.0.3
16.
com.sun.xml.messaging.saaj
saaj-impl
1.3
runtime
javax.xml.bind
jaxb-api
2.0
com.sun.xml.bind
jaxb-impl
2.0.3
6.) Be aware to use your BOM in your business service! Don't map stuff around. DRY! JAXB2 Generated beans are clean enough to use them as Domain Object Model. My MarshallingEndpoint remains pretty simple:
view plaincopy to clipboardprint?
1. @Override
2. protected Object invokeInternal(Object requestObject) throws Exception {
3. log.debug("invokeInternal");
4. WhoisRequest request = (WhoisRequest) requestObject;
5. WhoisResponse response = service.whois(request);
6. response.setResponseTimestamp(
7. .newXMLGregorianCalendar(new GregorianCalendar()));
8. return response;
9. }
@Override
protected Object invokeInternal(Object requestObject) throws Exception {
log.debug("invokeInternal");
WhoisRequest request = (WhoisRequest) requestObject;
WhoisResponse response = service.whois(request);
response.setResponseTimestamp(
.newXMLGregorianCalendar(new GregorianCalendar()));
return response;
}
7.) Use soapui to test your requests. Makes it pretty easy to test how it works, even with WS-Security enabled. (Password Digest for starters). Also, try to use a timestamp in your response, which is set by your technical layer. That way, you can quickly verify you get new responses.
soapui Testing Tool
8.) Don't separate a static WSDL and your XSD. Spring does not like that, and Maven neither. You'll end up with copying your xsd files anywhere in your project paths to have them in a) the Eclipse WSDL Editor b) the Eclipse XML Schema Editor c) the WEB-INF folder for the WebApp d) the test/resources source folder for unit tests e) in the webapp root for your browser/soap client to access the XSD. Use only one XSD, and import common types from another one.
Locations of resources
9.) Use transformWsdlLocations servlet parameter to get rid of the hardcoded localhost:808
"I played around with the Spring WebService library and this is a summary of what I did or what you need to take care of while implementing your own web service.
My toy project Whois-WS is about domain WHOIS information. You can ask the service about a domain name and it will return basic information about the domain, such as the domain name, connection status and responsible whois server.
To begin with, use the tutorial to start. You'll learn pretty fast with it. Really great tutorial and covers all the stuff to get warm with the topic.
1.) Take time to think about what your service does before you start developing your own service. Take care to not make your Business Object Model (BOM) too complex.
My example is going to be a password-secured WHOIS Service, which provides information about a domain name.
2.) Start with a simple "Hello World" example, use simple String input and String output. When you've got that running, go on and make your BOM with more complex types.
3.) Immediately document your BOM with XML Schema Annotations. Give examples for your values. That will be visible in the dynamically generated WSDL.
4.) The .wsdl file is always reachable at "/yourwebapp/foo.wsdl", with foo being the Bean ID of your WsdlDefinition.
5.) Use JAXB2 + Maven + Spring-WS. Besides spring-ws artifacts and junit, you'll need the following dependencies:
view plaincopy to clipboardprint?<dependency> <groupid>com.sun.xml.messaging.saaj</groupid> <artifactid>saaj-impl</artifactid> <version>1.3</version> <scope>runtime</scope> </dependency> <dependency> <groupid>javax.xml.bind</groupid> <artifactid>jaxb-api</artifactid> <version>2.0</version> </dependency> <dependency> <groupid>com.sun.xml.bind</groupid> <artifactid>jaxb-impl</artifactid> <version>2.0.3</version> </dependency>
com.sun.xml.messaging.saaj
saaj-impl
1.3
runtime
javax.xml.bind
jaxb-api
2.0
com.sun.xml.bind
jaxb-impl
2.0.3
6.) Be aware to use your BOM in your business service! Don't map stuff around. DRY! JAXB2 Generated beans are clean enough to use them as Domain Object Model. My MarshallingEndpoint remains pretty simple:
view plaincopy to clipboardprint?@Override protected Object invokeInternal(Object requestObject) throws Exception { log.debug("invokeInternal"); WhoisRequest request = (WhoisRequest) requestObject; WhoisResponse response = service.whois(request); response.setResponseTimestamp(DatatypeFactory.newInstance() .newXMLGregorianCalendar(new GregorianCalendar())); return response; } @Override
protected Object invokeInternal(Object requestObject) throws Exception {
log.debug("invokeInternal");
WhoisRequest request = (WhoisRequest) requestObject;
WhoisResponse response = service.whois(request);
response.setResponseTimestamp(DatatypeFactory.newInstance()
.newXMLGregorianCalendar(new GregorianCalendar()));
return response;
}
7.) Use soapui to test your requests. Makes it pretty easy to test how it works, even with WS-Security enabled. (Password Digest for starters). Also, try to use a timestamp in your response, which is set by your technical layer. That way, you can quickly verify you get new responses.
8.) Don't separate a static WSDL and your XSD. Spring does not like that, and Maven neither. You'll end up with copying your xsd files anywhere in your project paths to have them in a) the Eclipse WSDL Editor b) the Eclipse XML Schema Editor c) the WEB-INF folder for the WebApp d) the test/resources source folder for unit tests e) in the webapp root for your browser/soap client to access the XSD. Use only one XSD, and import common types from another one.
9.) Use transformWsdlLocations servlet parameter to get rid of the hardcoded localhost:8080 SOAP address location
view plaincopy to clipboardprint?<servlet> <servlet-name>spring-ws</servlet-name> <servlet-class>org.spring...MessageDispatcherServlet</servlet-class> <!-- Automatically transform the soap:adress location, so its not always localhost:8080 but dynamically adapts to where the service is deployed. Hopefully, he's using the Apache URL later, and not the internal Tomcat URL (mod_jk) --> <init-param> <param-name>transformWsdlLocations</param-name> <param-value>true</param-value> </init-param> </servlet>
spring-ws
org.spring...MessageDispatcherServlet
transformWsdlLocations
true
10) When you use SoapActionEndpointMapping and as client WebServiceTemplate, be sure to add the SOAPAaction request property to the client call, otherwise you will end up with "404 Not Found" errors."
- Playing with Spring WS - Mike`s Blog (view on Google Sidewiki)