Spring Web Services

602
-1

Published on

Spring Web Services

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
602
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
30
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Spring Web Services

  1. 1. Web services by Spring Way
  2. 2. Contract-last web services Contract-last web services does not require tomanipulate complex WSDL and XSD files. In contract-last web services a service class in Javais written and the web service framework “SOAP-ifies” it. When a web service is developed in contract last,its contract ends up being a reflection of theapplication’s internal API. Changes to the internal API will mean changes toyour service’s contract, which will ultimatelyrequire changes in the clients that are consumingyour service.
  3. 3. Contract-first web serviceStep Action Purpose1 Define the service contract This involves designing sample XMLmessages that will be processed by ourweb service. We’ll use these samplemessages to create XML Schema that willlater be used to create WSDL2 Write a service endpoint. We’ll create classes that will receive andprocess the messages sent to the webservice.3 Configure the endpoint andSpring-WS infrastructure.We’ll wire up our service endpoint alongwith a handful of Spring-WS beans that willtie everything together.
  4. 4. Defining the contract The messages that need to be sent and received from theservice are defined regardless of the serviceimplementation. A contract-first view of web services places emphasis on themessages that are sent to and received from services. Create sample XML input and output messages. <EvaluateHandRequest xmlns="http://www.springinaction.com/poker/schemas"> <card> <suit>HEARTS</suit> <face>TEN</face> </card> </EvaluateHandRequest>
  5. 5. Forging the data contract The contract is broken into two parts: data contract andoperational contract. The data contract defines the messages going in and outof the service. The messages include the schema definition of the<EvaluateHandRequest> and <EvaluateHandResponse>messages. The WSDL file usually contains an embedded XML Schemathat defines the data contract. The XML Schema (XSD) allows to precisely define whatshould go into a message. It can not only define what elements are in the message,but can also specify the types of those messages and placeconstraints on what data goes into the message
  6. 6. Operational Contract The operational contract defines the operations that ourservice will perform. SOAP operation does not necessarily correspond to amethod in the service’s API. The WSDL file except the embeded schema defines theoperational contract, including one or more<wsdl:operation> elements within the <wsdl:binding>element.
  7. 7. Handling messages with serviceendpoints A web service client interacts with a Spring-WS applicationthrough one of several message endpoints. A message endpoint is a class that receives an XMLmessage from the client and, based on the content of themessage, makes calls to internal application objects toperform the actual work. Once the endpoint has completed processing, it returns itsresponse in XML output message. Message endpoints process incoming XML messages andproduce XML responses.
  8. 8. Message endpoint in Spring-WSAbstract Endpoint Class DescriptionAbstractDom4jPayloadEndpoint Handles message payloads as dom4jElementsAbstractDomPayloadEndpoint Handles message payloads as DOMElementsAbstractJDomPayloadEndpoint Handles message payloads as JDOMElementsAbstractMarshallingPayloadEndpoint Unmarshals the request payload into anobject and marshals the response objectinto XMLAbstractSaxPayloadEndpoint Handles message payloads through aSAX ContentHandler implementationAbstractStaxEventPayloadEndpoint Handles message payloads using event-based StAXAbstractStaxStreamPayloadEndpoint Handles message payloads usingstreaming StAXAbstractXomPayloadEndpoint Handles message payloads as XOMElements
  9. 9. JDOM-based message endpoint public class EvalDomEndpoint extends AbstractJDomPayloadEndpoint implements InitializingBean { private Namespace namespace; private XPath cardsXPath; private XPath suitXPath; private XPathfaceXPath protected Element invokeInternal(Element element) throws Exception { Card cards[] = extractCardsFromRequest(element); PokerHand pokerHand = new PokerHand(); pokerHand.setCards(cards); PokerHandType handType = pokerHandEvaluator.evaluateHand(pokerHand); return createResponse(handType); } private Element createResponse(PokerHandType handType) { Element responseElement = new Element("EvaluateHandResponse", namespace); responseElement.addContent( new Element("handName", namespace).setText(handType.toString())); return responseElement; }
  10. 10. JDOM-based message endpoint private Card[] extractCardsFromRequest(Element element) throws JDOMException { Card[] cards = new Card[5]; List cardElements = cardsXPath.selectNodes(element); for(int i=0; i < cardElements.size(); i++) { Element cardElement = (Element) cardElements.get(i); Suit suit = Suit.valueOf( suitXPath.valueOf(cardElement)); Face face = Face.valueOf( faceXPath.valueOf(cardElement)); cards[i] = new Card(); cards[i].setFace(face); cards[i].setSuit(suit); } return cards; } public void afterPropertiesSet() throws Exception { namespace = Namespace.getNamespace("poker", "http://www.springinaction.com/poker/schemas"); cardsXPath = XPath.newInstance("/poker:EvaluateHandRequest/poker.card"); cardsXPath.addNamespace(namespace); faceXPath = XPath.newInstance("poker:face"); faceXPath.addNamespace(namespace); suitXPath = XPath.newInstance("poker:suit"); suitXPath.addNamespace(namespace); }
  11. 11. JDOM-based message endpoint public class EvaluateHandJDomEndpoint extends AbstractJDomPayloadEndpointimplements InitializingBean { private Namespace namespace; private XPath cardsXPath; private XPath suitXPath; private XPath faceXPath; protected Element invokeInternal(Element element) throws Exception { Card cards[] = extractCardsFromRequest(element); PokerHand pokerHand = new PokerHand(); pokerHand.setCards(cards); PokerHandType handType = pokerHandEvaluator.evaluateHand(pokerHand); return createResponse(handType); } private Element createResponse(PokerHandType handType) { Element responseElement = new Element("EvaluateHandResponse", namespace); responseElement.addContent(new Element("handName",namespace).setText(handType.toString())); return responseElement; }
  12. 12.  private Card[] extractCardsFromRequest(Element element) throws JDOMException { Card[] cards = new Card[5]; List cardElements = cardsXPath.selectNodes(element); for(int i=0; i < cardElements.size(); i++) { Element cardElement = (Element) cardElements.get(i); Suit suit = Suit.valueOf(suitXPath.valueOf(cardElement)); Face face = Face.valueOf(faceXPath.valueOf(cardElement)); cards[i] = new Card(); cards[i].setFace(face); cards[i].setSuit(suit); } return cards; } public void afterPropertiesSet() throws Exception { namespace = Namespace.getNamespace("poker", "http://www.springinaction.com/poker/schemas"); cardsXPath = XPath.newInstance("/poker:EvaluateHandRequest/poker.card"); cardsXPath.addNamespace(namespace); faceXPath = XPath.newInstance("poker:face"); faceXPath.addNamespace(namespace); suitXPath = XPath.newInstance("poker:suit"); suitXPath.addNamespace(namespace); } // injected private PokerHandEvaluator pokerHandEvaluator; public void setPokerHandEvaluator(PokerHandEvaluator pokerHandEvaluator) { this.pokerHandEvaluator = pokerHandEvaluator; } }
  13. 13. JDOM-based message endpoint The invokeInternal() method is the entry point to the endpoint. The invokeInternal() gets a JDOM Element object containing theincoming message, which is the <EvaluateHandRequest>. The Element object is forwarded to extractCardsFromRequest(). After getting an array of Card objects, invokeInternal() passesthose Cards to an injected PokerHandEvaluator’sevaluateHand(), to evaluate the poker hand (has actual businesslogic). The invokeInternal() passes the PokerHandType object off tocreateResponse() to produce an <EvaluateHandResponse>element using JDOM. The resulting JDOM Element is returned andEvaluateHandJDomEndpoint’s job is done.
  14. 14. Marshaling message payloads AbstractMarshallingPayloadEndpoint is given an object toprocess instead of an XML Element to pull apart for information. A marshaling endpoint works with an unmarshaler that convertsan incoming XML message into a POJO and a marshaler whichconverts the POJO into an XML message to be returned to theclient. AbstractMarshallingPayloadEndpoint has a reference to an XMLmarshaler which it uses to turn the XML message into an objectand vice versa. The key benefit of EvaluateHandMarshallingEndpoint is that itcan be unit tested similar to any other POJO.
  15. 15. AbstractMarshallingPayloadEndpoint Request Processing public class EvaluateHandMarshallingEndpoint extendsAbstractMarshallingPayloadEndpoint { protected Object invokeInternal(Object object) throws Exception { EvaluateHandRequest request = (EvaluateHandRequest) object; PokerHand pokerHand = new PokerHand(); pokerHand.setCards(request.getHand()); PokerHandType pokerHandType = pokerHandEvaluator.evaluateHand(pokerHand); return new EvaluateHandResponse(pokerHandType); } // injected private PokerHandEvaluator pokerHandEvaluator; public void setPokerHandEvaluator( PokerHandEvaluator pokerHandEvaluator) { this.pokerHandEvaluator = pokerHandEvaluator; } }
  16. 16. Wiring Spring-WS Spring-WS can be fronted by MessageDispatcherServlet, asubclass of DispatcherServlet that knows how to dispatch SOAPrequests to Spring-WS endpoints. <servlet> <servlet-name>poker</servlet-name> <servlet-class>org.springframework.ws.transport.http. ➥ MessageDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>poker</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
  17. 17. Spring-WS service configuration
  18. 18. Spring-WS service configuration ■ payloadMapping—Maps incoming XML messages to an appropriate endpoint. In this case, we’ll use a mapping that looks up endpoints using the incoming XML’s root element (by its qualified name). ■ evaluateHandEndpoint—This is the endpoint that will process the incoming XML message for the poker hand evaluation service. ■ marshaller—The evaluateHandEndpoint could be written to process the incoming XML as a DOM or JDOM element, or even as a SAX event handler. Instead, the marshaller bean will automatically convert XML to and from Java objects. ■ pokerHandEvaluator—This is a POJO that performs the actual poker hand processing. evaluateHandEndpoint will use this bean to do its work. ■ endpointExceptionResolver—This is a Spring-WS bean that will automatically convert any Java exceptions thrown while processing a request into appropriate SOAP faults. ■ poker—Although it’s not obvious from its name, this bean will serve the WSDL for the poker hand web service to the client. Either it can serve handcreated WSDL or it can be wired to automatically generate WSDL from the message’s XML Schema.
  19. 19. Mapping messages to endpoints The incoming messages need to be mapped to the endpoints thatprocess them. MessageDispatcherServlet uses an endpoint mapping to decide whichendpoint should receive an incoming XML message. <bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping. PayloadRootQNameEndpointMapping"> <property name="endpointMap"> <map> <entry key= "{http://www.springinaction.com/poker/schemas} EvaluateHandRequest" value-ref="evaluateHandEndpoint" /> </map> </property> </bean>
  20. 20. Mapping messages to endpoints PayloadRootQNameEndpointMapping mapsincoming SOAP messages to endpoints by examiningthe qualified name (QName) of the message’s payloadand looking up the endpoint from its list of mappings(configured through the endpointMap property). The QName is mapped to a bean namedevaluateHandEndpoint
  21. 21. Wiring Service Endpoint The JDOM-based endpoint then it is configured in Spring asfollows: <bean id="evaluateHandEndpoint" class="com.springinaction.poker.webservice. EvaluateHandJDomEndpoint"> <property name="pokerHandEvaluator" ref="pokerHandEvaluator" /> </bean> The EvaluateHandJDomEndpoint delegates to animplementation of PokerHandEvaluator which evaluates thepoker hand.
  22. 22. Wiring Service Endpoint The EvaluateHandMarshallingEndpoint configuration: <bean id="evaluateHandEndpoint" class="com.springinaction.poker.webservice. EvaluateHandMarshallingEndpoint"> <property name="marshaller" ref="marshaller" /> <property name="unmarshaller" ref="marshaller" /> <property name="pokerHandEvaluator" ref="pokerHandEvaluator" /> </bean> Alongwith the pokerHandEvaluator property, the marshalingendpoint must have its marshaller and unmarshaller propertiesset as well.
  23. 23. Configuring a message marshaler The key to translating objects to and from XMLmessages is object-XML mapping (OXM). The central elements of Spring-OXM are its Marshallerand Unmarshaller interfaces. Marshaller are used to generate XML elements fromJava objects while Unmarshaller are used to constructJava objects from XML elements. AbstractMarshallingPayloadEndpoint takes advantageof the Spring-OXM marshalers and unmarshalerswhen processing messages.
  24. 24. Spring-OXM MarshallersOXM solution Spring-OXM marshalerCastor XML org.springframework.oxm.castor.CastorMarshallerJAXB v1 org.springframework.oxm.jaxb.Jaxb1MarshallerJAXB v2 org.springframework.oxm.jaxb.Jaxb2MarshallerJiBX org.springframework.oxm.jibx.JibxMarshallerXMLBeans org.springframework.oxm.xmlbeans.XmlBeansMarshallerXStream org.springframework.oxm.xstream.XStreamMarshaller(limited support for XML namespaces)
  25. 25. Sample Castor XML Mapping <?xml version="1.0"?> <mapping xmlns="http://castor.exolab.org/"> <class name="com.springinaction.poker.webservice. ➥ EvaluateHandRequest"> <map-to xml="EvaluateHandRequest" /> <field name="hand" collection="array" type="com.springinaction.poker.Card" required="true"> <bind-xml name="card" node="element" /> </field> </class> </mapping>
  26. 26. Handling endpoint exceptions Java exceptions thrown by web servicesshould beconverted into SOAP faults. SoapFaultMappingExceptionResolver handles anyuncaught exceptions that occur in the course ofhandling a message and produce an appropriate SOAPfault that will be sent back to the client.
  27. 27. SoapFaultMappingExceptionResolver <bean id="endpointExceptionResolver" class="org.springframework.ws.soap.server.endpoint. ➥ SoapFaultMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.springframework.oxm. ➥ UnmarshallingFailureException"> SENDER,Invalid message received</prop> <prop key="org.springframework.oxm. ➥ ValidationFailureException"> SENDER,Invalid message received</prop> </props> </property> <property name="defaultFault“ value="RECEIVER,Server error" /> </bean>
  28. 28. SoapFaultMappingExceptionResolver The exceptionMappings property is configured with one ormore SOAP fault definitions mapped to Java exceptions. The key of each <prop> is a Java exception which needs tobe translated to a SOAP fault. The value of the <prop> is a two-part value where the firstpart is the type of fault that is to be created and the secondpart is a string that describes the fault. SOAP faults come in two types: sender and receiver faults. Sender faults indicate that the problem is on the client. Receiver faults indicate that the message received from theclient is having some processing problem.
  29. 29. Serving WSDL files DynamicWsdl11Definition is a special bean thatMessageDispatcherServlet works with to generate WSDL fromXML Schema. DynamicWsdl11Definition works by reading an XML Schemadefinition, specified here as PokerTypes.xsd by the schemaproperty. DynamicWsdl11Definition reads an XML Schema definitionspecified by the schema property. It looks through the schema file for any element definitionswhose names end with Request and Response. It assumes that those suffixes indicate a message that is to besent to or from a web service operation and creates acorresponding <wsdl:operation> element in the WSDL itproduces.
  30. 30. DynamicWsdl11Definition <bean id="poker" class="org.springframework.ws.wsdl.wsdl11. ➥ DynamicWsdl11Definition"> <property name="builder"> <bean class="org.springframework.ws.wsdl.wsdl11.builder. ➥ XsdBasedSoap11Wsdl4jDefinitionBuilder"> <property name="schema" value="/PokerTypes.xsd"/> <property name="portTypeName" value="Poker"/> <property name="locationUri" value="http://localhost:8080/Poker-WS/services"/> </bean> </property> </bean>
  31. 31. DynamicWsdl11Definition Config <wsdl:portType name="Poker"> <wsdl:operation name="EvaluateHand"> <wsdl:input message="schema:EvaluateHandRequest" name="EvaluateHandRequest"> </wsdl:input> <wsdl:output message="schema:EvaluateHandResponse" name="EvaluateHandResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType>
  32. 32. URL Mapping A new <servletmapping> is added to web.xml so thatMessageDispatcherServlet will serve WSDLdefinitions.<servlet-mapping><servlet-name>poker</servlet-name><url-pattern>*.wsdl</url-pattern></servlet-mapping
  33. 33. Predefined WSDL SimpleWsdl11Definition serves the WSDL provided through the wsdl property. <bean id="poker" class="org.springframework.ws.wsdl.wsdl11. ➥ SimpleWsdl11Definition"> <property name="wsdl" value="/PokerService.wsdl"/> </bean> MessageDispatcherServlet can rewrite the service’s location specified in staticWSDL every time it is deployed. It requires to set an <init-param> named transformWsdlLocations to true inMessageDispatcherServlet. <servlet> <servlet-name>poker</servlet-name> <servlet-class>org.springframework.ws.transport.http. ➥ MessageDispatcherServlet</servlet-class> <init-param> <param-name>transformWsdlLocations</param-name> <param-value>true</param-value> </init-param> </servlet>
  34. 34. Consuming Spring Web services WebServiceTemplate is the centerpiece of Spring-WS’sclient API. It employs the Template design pattern to provide theability to send and receive XML messages frommessage-centric web services.
  35. 35. Configuring WebServiceTemplate <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> <property name="messageFactory"> <bean class="org.springframework.ws.soap.saaj. ➥ SaajSoapMessageFactory"/> </property> <property name="messageSender" ref="messageSender"/> </bean> <bean id="messageSender" class="org.springframework.ws.transport.http. ➥ HttpUrlConnectionMessageSender"> <property name="url" value="http://localhost:8080/Poker-WS/services"/> </bean>
  36. 36. WebServiceTemplate WebServiceTemplate constructs the message andsends it to the web service. The object wired into the messageFactory propertyhandles the task of constructing the message. It should be wired with an implementation of Spring-WS’s WebServiceMessageFactory interface. SaajSoapMessageFactory is the default message factoryused by MessageDispatcherServlet.
  37. 37. Message Factory ImplementationsMessage factory What it doesAxiomSoapMessageFactory Produces SOAP messages using the AXIs ObjectModel (AXIOM). Based on the StAX streaming XMLAPI. Useful when working with large messages andperformance is a problem.DomPoxMessageFactory Produces Plain Old XML (POX) messages using aDOM. Use this message factory when neither theclient nor the service cares to deal with SOAPSaajSoapMessageFactory Produces SOAP messages using the SOAP withAttachments API for Java (SAAJ). Because SAAJ usesa DOM, large messages could consume a lot ofmemory. If performance becomes an issue, considerusing AxiomSoapMessageFactory instead.
  38. 38. WebServiceMessageSender The messageSender property should be wired with areference to an implementation of aWebServiceMessageSender. The url property specifies the location of the service and itmatches the URL in the service’s WSDL definition.Message sender What it doesCommonsHttpMessageSender Sends the message using JakartaCommons HTTP Client. Supports apreconfigured HTTP client, allowingadvanced features such as HTTPauthentication and HTTP connectionpooling.HttpUrlConnectionMessageSender Sends the message using Java’s basicfacilities for HTTP connections.Provides limited functionality.
  39. 39. Sending a message The sendAndReceive() method takes ajava.xml.transform.Source and ajava.xml.transform.Result as parameters to send themessage. The Source object represents the message payload tosend to the web service. The Result object is to be populated with the messagepayload returned from the service. public boolean sendAndReceive(SourcerequestPayload, Result responseResult) throws IOException
  40. 40. WebServiceTemplate Implementation public PokerHandType evaluateHand(Card[] cards) throws IOException { Element requestElement = new Element("EvaluateHandRequest"); Namespace ns = Namespace.getNamespace( "http://www.springinaction.com/poker/schemas"); requestElement.setNamespace(ns); Document doc = new Document(requestElement); // Process the Request message JDOMSource requestSource = new JDOMSource(doc); JDOMResult result = new JDOMResult(); webServiceTemplate.sendAndReceive(requestSource, result); Document resultDocument = result.getDocument(); Element responseElement = resultDocument.getRootElement(); Element handNameElement = responseElement.getChild("handName", ns); return PokerHandType.valueOf(handNameElement.getText()); }
  41. 41. Marshalers on Client side WebServiceTemplate provides marshalSendAndReceive()method for sending and receiving XML messages that aremarshaled to and from Java objects. public class MarshallingPokerClient implements PokerClient { public PokerHandType evaluateHand(Card[] cards) throws IOException { EvaluateHandRequest request = new EvaluateHandRequest(); request.setHand(cards); EvaluateHandResponse response = (EvaluateHandResponse) webServiceTemplate.marshalSendAndReceive(request); return response.getPokerHand(); } }
  42. 42. WebServiceTemplate with Marshalers
  43. 43. Marshaler Configuration <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> <property name="messageFactory"> <bean class="org.springframework.ws.soap.saaj. ➥ SaajSoapMessageFactory"/> </property> <property name="messageSender"ref="urlMessageSender"/> <property name="marshaller" ref="marshaller" /> <property name="unmarshaller" ref="marshaller" /> </bean>
  44. 44. Web Service Gateway Support WebServiceGatewaySupport is a convenient support class thatautomatically provides a WebServiceTemplate to client classesthat subclass it, without injecting with a WebServiceTemplate. public class PokerServiceGateway extends WebServiceGatewaySupport implements PokerClient { public PokerHandType evaluateHand(Card[] cards) throws IOException { EvaluateHandRequest request = new EvaluateHandRequest(); request.setHand(cards); EvaluateHandResponse response = (EvaluateHandResponse) getWebServiceTemplate().marshalSendAndReceive(request); return response.getPokerHand(); } }

×