Скачать презентацию Contract-First Web Services with Spring-WS Craig Walls Gateway Скачать презентацию Contract-First Web Services with Spring-WS Craig Walls Gateway

9fdf9720fdfd8b5eb778855d97ed9ffd.ppt

  • Количество слайдов: 64

Contract-First Web Services with Spring-WS Craig Walls Gateway Software Symposium 2007 craig@habuma. com Blog: Contract-First Web Services with Spring-WS Craig Walls Gateway Software Symposium 2007 [email protected] com Blog: http: //www. springinaction. com Wiki: http: //wiki. habuma. com

Who are you? • Java: 6? 5? 1. 4? 1. 3? 1. 2? 1. Who are you? • Java: 6? 5? 1. 4? 1. 3? 1. 2? 1. 1? • Spring: 1. 2? 2. 0? 2. 1? • Web-Services: Axis? X-Fire? Glue? Spring-WS? • Favorite session so far? • What brings you to this session?

About me • Agile developer with Semantra – Natural language business intelligence • Developing About me • Agile developer with Semantra – Natural language business intelligence • Developing software professionally for over 13 years – Telecom, Finance, Retail, Education – Java for most of that – Also some C/C++, C#/. NET, Ruby • Spring fanatic

Agenda • • Spring remoting and web services Contract-first Designing the contract Introducing Spring-WS Agenda • • Spring remoting and web services Contract-first Designing the contract Introducing Spring-WS Building service endpoints Wiring it all together Final thoughts Q&A

Spring remoting and web services Building a service using XFire Spring remoting and web services Building a service using XFire

Spring Remoting Overview • Client side: – Proxy. Factory. Bean : Produces wire-able proxy Spring Remoting Overview • Client side: – Proxy. Factory. Bean : Produces wire-able proxy to a remote service • Service side: – Remote exporter : Exports a Springconfigured POJO as a service • Available in RMI, Hessian, Burlap, Http. Invoker flavors • Spring doesn’t provide an exporter for SOAP web services…however…

XFire • Full-featured web-services stack • Comes with full Spring remoting support – XFire. XFire • Full-featured web-services stack • Comes with full Spring remoting support – XFire. Client. Factory. Bean : A client-side factory bean that produces a proxy for remote service – XFire. Exporter : A Spring remote exporter to export POJOs as web services • http: //xfire. codehaus. org

Exporting an XFire service 1. Configure the POJO as a Spring <bean> 2. Configure Exporting an XFire service 1. Configure the POJO as a Spring 2. Configure the XFire. Exporter to export the service 3. Configure Spring’s Dispatcher. Servlet in web. xml 4. Configure a handler-mapping to map URLs to the XFire. Exporter

Using JSR-181 annotations 1. 2. 3. 4. Annotate bean class and methods Declare as Using JSR-181 annotations 1. 2. 3. 4. Annotate bean class and methods Declare as in Spring Configure Spring Dispatcher. Servlet Configure a Jsr 181 Handler. Mapping in Spring

What if the POJO changes? • The focus is on the POJO, not the What if the POJO changes? • The focus is on the POJO, not the contract. – The service is method-centric, not message -centric • The service’s contract is only a byproduct of the export. • Consequently, the contract is volatile. – (That’s a bad thing!)

Contract Last • The most important piece of a service is NOT the implementation--it’s Contract Last • The most important piece of a service is NOT the implementation--it’s the contract. • Nevertheless, many service developers treat the contract as a second-class citizen. – Some don’t even think about it at all.

Contract-first web services Contract-first web services

The solution: Contract-first • If the contract is so important, then why not elevate The solution: Contract-first • If the contract is so important, then why not elevate it to the position it deserves. • Create the contract first – Then write code that satisfies the contract – Not necessarily implement the contract.

WSDL-first is NOT contract-first • In the WSDL-first approach, WSDL is used to generate WSDL-first is NOT contract-first • In the WSDL-first approach, WSDL is used to generate service skeletons. – Not unlike using IDL compilers to generate CORBA service skeletons • Resulting skeletons are coupled to the contract. – Changes to the contract change the skeletons

It’s all in the message! • Contract-last services are operationcentric – A service is It’s all in the message! • Contract-last services are operationcentric – A service is defined by its operations (which translate to methods) • Contract-first services are messagecentric – A service is defined by the messages it processes and returns.

The contract • WSDL + XSD • Operational contract: WSDL describes what the service The contract • WSDL + XSD • Operational contract: WSDL describes what the service can do. • Data contract: XSD describes the messages sent to the service.

Contact-first: Basic steps 1. Define the messages (XML) 2. Create the data contract (XSD) Contact-first: Basic steps 1. Define the messages (XML) 2. Create the data contract (XSD) 3. Create the operational contract (WSDL) 4. Develop an endpoint to process the messages (Spring-WS) 5. Map messages to endpoints 6. Deploy

Defining the contract Don’t leave…it ain’t as bad as you think!!! Defining the contract Don’t leave…it ain’t as bad as you think!!!

Create sample messages • Write out XML that resembles what you want passed in Create sample messages • Write out XML that resembles what you want passed in and out of your service. • Believe it or not, this is the hardest part.

HEARTS TEN " src="http://present5.com/presentation/9fdf9720fdfd8b5eb778855d97ed9ffd/image-20.jpg" alt="Poker. Hand. Request HEARTS TEN " /> Poker. Hand. Request HEARTS TEN SPADES KING HEARTS KING DIAMONDS TEN CLUBS TEN

Full House Full House Poker. Hand. Response Full House

Create the data contract • Create XML Schema that can be used to validate Create the data contract • Create XML Schema that can be used to validate sample messages • Options: – Write it by hand (not much fun) – Infer it • Inferred XSD is never perfect. Will require some fine-tuning by hand. – But at least you don’t have to write it all by hand.

XSD Inference tools • Microsoft’s XSD inference tool – http: //msdn 2. microsoft. com/en-us/xml/Bb XSD Inference tools • Microsoft’s XSD inference tool – http: //msdn 2. microsoft. com/en-us/xml/Bb 190622. aspx • Trang – http: //www. thaiopensource. com/relaxng/trang. html • Nocternity (Perl script) – http: //projects. nocternity. net/xsd-inference/

Create operational contract • Write WSDL • Options: – Write it by hand (not Create operational contract • Write WSDL • Options: – Write it by hand (not much fun) – Infer it • Generated WSDL is never perfect. Will require some fine-tuning by hand. – Again, you didn’t write it all by hand.

Introducing Spring-WS Introducing Spring-WS

What is Spring-WS • Web services framework that encourages contract-first development • Web services What is Spring-WS • Web services framework that encourages contract-first development • Web services are implemented as service endpoints – Endpoints process XML messages – Conceptually similar to Spring MVC • Includes Object-XML Mapping framework • http: //static. springframework. org/springws/site – Current version 1. 0. 1 (released yesterday!!!)

Spring-WS and Spring MVC • Dispatcher. Servlet • Handler mapping • Controller – Command Spring-WS and Spring MVC • Dispatcher. Servlet • Handler mapping • Controller – Command controller • Simple. Mapping Exception. Resolver Spring-WS • Message. Dispatcher • Endpoint mapping • Endpoint – Marshalling endpoint • Soap. Fault. Mapping Exception. Resolver

Spring OXM • Abstraction framework over several popular XML marshalling APIs. • Used by Spring OXM • Abstraction framework over several popular XML marshalling APIs. • Used by Spring-WS to (un)marshal objects for endpoints. – Can also be used for general purpose XML marshalling.

Supported marshalling APIs • • • Castor XML JAXB (v 1 and v 2) Supported marshalling APIs • • • Castor XML JAXB (v 1 and v 2) Ji. BX XMLBeans XStream

Building service endpoints Building service endpoints

Service endpoints • Process XML message • Several Spring-WS base classes: – – – Service endpoints • Process XML message • Several Spring-WS base classes: – – – – Abstract. Dom 4 j. Payload. Endpoint Abstract. Dom. Payload. Endpoint Abstract. JDom. Payload. Endpoint Abstract. Marshalling. Payload. Endpoint Abstract. Sax. Payload. Endpoint Abstract. Stax. Event. Payload. Endpoint Abstract. Stax. Stream. Payload. Endpoint Abstract. Xom. Payload. Endpoint • Spring-WS 1. 0. 0 added support for annotation-based endpoints – @Endpoint, @Payload. Root, @XPath. Param

Abstract. JDom. Payload. Endpoint • Endpoint is given a JDom Element to process and Abstract. JDom. Payload. Endpoint • Endpoint is given a JDom Element to process and must return a JDom Element: • Can use XPath queries to pull info out of Element objects. public class Evaluate. Hand. JDom. Endpoint extends Abstract. JDom. Payload. Endpoint implements Initializing. Bean { protected Element invoke. Internal(Element element) throws Exception { … // process message } }

Abstract. Marshalling. Payload. Endpoint • Given an Object and must return an Object. • Abstract. Marshalling. Payload. Endpoint • Given an Object and must return an Object. • Uses Spring’s OXM framework. – XML message is unmarshalled into Object. Returned object is marshalled into XML. public class Evaluate. Hand. Marshalling. Endpoint extends Abstract. Marshalling. Payload. Endpoint { protected Object invoke. Internal(Object object) throws Exception { Purchase. Order po = (Purchase. Order) object; … // Process purchase order } }

Annotation-based endpoint • Uses annotations to declare endpoints – Minimizes Spring XML configuration – Annotation-based endpoint • Uses annotations to declare endpoints – Minimizes Spring XML configuration – Allows for more POJO(ish) endpoints – Helps with XML parsing • Three annotations… – @Endpoint - Declares a class as an endpoint – @Payload. Root - Specifies a method as the destination for a payload message – @XPath. Param - Defines how to parse message into method parameter

Annotation-based endpoint package com. springinaction. poker. webservice; import org. springframework. ws. server. endpoint. annotation. Annotation-based endpoint package com. springinaction. poker. webservice; import org. springframework. ws. server. endpoint. annotation. Endpoint; import org. springframework. ws. server. endpoint. annotation. Payload. Root; import com. springinaction. poker. Poker. Hand. Evaluator; import com. springinaction. poker. Poker. Hand. Type; @Endpoint public class Evaluate. Hand. Annotated. Endpoint { @Payload. Root(namespace = "http: //www. springinaction. com/poker/schemas", local. Part = "Evaluate. Hand. Request") public Evaluate. Hand. Response evaluate. Hand(Evaluate. Hand. Request request) { Poker. Hand. Type hand. Type = poker. Hand. Evaluator. evaluate. Hand(new Poker. Hand( request. get. Hand())); return new Evaluate. Hand. Response(hand. Type); } // injected private Poker. Hand. Evaluator poker. Hand. Evaluator; public void set. Poker. Hand. Evaluator(Poker. Hand. Evaluator poker. Hand. Evaluator) { this. poker. Hand. Evaluator = poker. Hand. Evaluator; } }

Wiring it all together in Spring Wiring it all together in Spring

Spring-WS: The big picture Maps message payloads to endpoints Endpoint Implementation Business logic happens Spring-WS: The big picture Maps message payloads to endpoints Endpoint Implementation Business logic happens here Marshals XML messages to/from POJOs Converts exceptions to SOAP faults Magically generates WSDL from XSD

Message. Dispatcher. Servlet • Spring-WS is based on Spring MVC • Must configure a Message. Dispatcher. Servlet • Spring-WS is based on Spring MVC • Must configure a Dispatcher. Servlet in web. xml… – Actually, Message. Dispatcher. Servlet poker org. springframework. ws. transport. http. Message. Dispatcher. Servlet transform. Wsdl. Locations true poker /services/* poker *. wsdl

Endpoint mappings • Helps message dispatcher decide where messages should be sent • Two Endpoint mappings • Helps message dispatcher decide where messages should be sent • Two kinds: – Payload. Root. QName. Endpoint. Mapping – Soap. Action. Endpoint. Mapping When this kind of message arrives… Send it to this endpoint

Annotation endpoint mappings • If using annotation-based endpoints… <bean class= Annotation endpoint mappings • If using annotation-based endpoints… – Note that namespace/local-name of message are specified in @Payload. Root • If marshaling, you’ll need a Marshalling. Method. Endpoint. Adapter:

Wiring the endpoint <bean id= Wiring the endpoint

A marshalling endpoint <bean id= A marshalling endpoint Automatically maps XML to/from objects

An (un)marshaller: Castor

Loose-end: Exceptions • What about exceptions? – How are they mapped to SOAP faults? Loose-end: Exceptions • What about exceptions? – How are they mapped to SOAP faults? – Soap. Fault. Mapping. Exception. Resolver SENDER, Invalid request SENDER, Invalid request

Loose-end: Service location • The service location is hard-coded in the WSDL? – What Loose-end: Service location • The service location is hard-coded in the WSDL? – What if the service is deployed somewhere other than localhost? – Simple. Wsdl 11 Definition serves WSDL, transforming locations to match request’s server and context.

Or…Dynamic. Wsdl 11 Definition • Dynamic. Wsdl 11 Definition automatically generates WSDL from the Or…Dynamic. Wsdl 11 Definition • Dynamic. Wsdl 11 Definition automatically generates WSDL from the message XSD

Consuming Spring-WS services Consuming Spring-WS services

A word about writing clients • Proxy-based client APIs typically won’t work with Spring-WS A word about writing clients • Proxy-based client APIs typically won’t work with Spring-WS – Proxies are method-centric and very RPCish in nature. • What does work is… – WSDL 2 Java-generated client stubs – Anything that can wrap supplied XML in a SOAP wrapper – Spring-WS client-side templates

Using Spring-WS’ client API • Template-based – Much like Spring JDBC, Spring JMS, etc Using Spring-WS’ client API • Template-based – Much like Spring JDBC, Spring JMS, etc • Choices to make: – To marshal or not to marshal? – Basic template or gateway support?

Spring-WS Client API • Web. Service. Template - Centerpiece of Spring-WS client API (similar Spring-WS Client API • Web. Service. Template - Centerpiece of Spring-WS client API (similar in concept to Spring’s JDBC Template) • Message factory - Produces message • Message sender - Sends message • (Un)Marshaler (optional)- Converts XML to/from POJO

Spring-WS Client API Spring-WS Client API

Simple template-based client package com. springinaction. ws. client; import java. io. IOException; import org. Simple template-based client package com. springinaction. ws. client; import java. io. IOException; import org. jdom. Document; import org. jdom. Element; import org. jdom. Namespace; import org. jdom. transform. JDOMResult; import org. jdom. transform. JDOMSource; import org. springframework. ws. client. core. Web. Service. Template; import com. springinaction. poker. Card; import com. springinaction. poker. Poker. Hand. Type; public class Template. Based. Poker. Client implements Poker. Client { public Poker. Hand. Type evaluate. Hand(Card[] cards) throws IOException { // DETAILS OF THIS METHOD ARE ON THE NEXT SLIDE!!! } // INJECTED private Web. Service. Template web. Service. Template; public void set. Web. Service. Template(Web. Service. Template web. Service. Template) { this. web. Service. Template = web. Service. Template; } }

Simple template-based client (2) public Poker. Hand. Type evaluate. Hand(Card[] cards) throws IOException { Simple template-based client (2) public Poker. Hand. Type evaluate. Hand(Card[] cards) throws IOException { Element request. Element = new Element("Evaluate. Hand. Request"); Namespace ns = Namespace. get. Namespace( "http: //www. springinaction. com/poker/schemas"); request. Element. set. Namespace(ns); Document doc = new Document(request. Element); for (int i = 0; i < cards. length; i++) { Element card. Element = new Element("card"); Element suit. Element = new Element("suit"); suit. Element. set. Text(cards[i]. get. Suit(). to. String()); Element face. Element = new Element("face"); face. Element. set. Text(cards[i]. get. Face(). to. String()); card. Element. add. Content(suit. Element); card. Element. add. Content(face. Element); doc. get. Root. Element(). add. Content(card. Element); } JDOMResult result = new JDOMResult(); web. Service. Template. send. Source. And. Receive. To. Result(new JDOMSource(doc), result); Document result. Document = result. get. Document(); Element response. Element = result. Document. get. Root. Element(); Element hand. Name. Element = response. Element. get. Child("hand. Name", ns); return Poker. Hand. Type. value. Of(hand. Name. Element. get. Text()); } Construct request message Send message Parse result

Simple template-based client (3) <bean id= Simple template-based client (3)

Marshaling template client package com. springinaction. ws. client; import java. io. IOException; import org. Marshaling template client package com. springinaction. ws. client; import java. io. IOException; import org. springframework. ws. client. core. Web. Service. Template; import com. springinaction. poker. Card; import com. springinaction. poker. Poker. Hand. Type; import com. springinaction. poker. webservice. Evaluate. Hand. Request; import com. springinaction. poker. webservice. Evaluate. Hand. Response; public class Marshalling. Poker. Client implements Poker. Client { public Poker. Hand. Type evaluate. Hand(Card[] cards) throws IOException { Evaluate. Hand. Request request = new Evaluate. Hand. Request(); request. set. Hand(cards); Evaluate. Hand. Response response = (Evaluate. Hand. Response) web. Service. Template. marshal. Send. And. Receive(request); return response. get. Poker. Hand(); Marshal and send } // INJECTED private Web. Service. Template web. Service. Template; public void set. Web. Service. Template(Web. Service. Template web. Service. Template) { this. web. Service. Template = web. Service. Template; } } Template is injected

Marshaling template client (2) <bean id= Marshaling template client (2)

Gateway-based client package com. springinaction. ws. client; import java. io. IOException; import org. springframework. Gateway-based client package com. springinaction. ws. client; import java. io. IOException; import org. springframework. ws. client. core. support. Web. Service. Gateway. Support; import com. springinaction. poker. Card; import com. springinaction. poker. Poker. Hand. Type; import com. springinaction. poker. webservice. Evaluate. Hand. Request; import com. springinaction. poker. webservice. Evaluate. Hand. Response; public class Poker. Client. Gateway extends Web. Service. Gateway. Support implements Poker. Client { public Poker. Hand. Type evaluate. Hand(Card[] cards) throws IOException { Evaluate. Hand. Request request = new Evaluate. Hand. Request(); request. set. Hand(cards); Evaluate. Hand. Response response = (Evaluate. Hand. Response) get. Web. Service. Template(). marshal. Send. And. Receive(request); return response. get. Poker. Hand(); } }

" src="http://present5.com/presentation/9fdf9720fdfd8b5eb778855d97ed9ffd/image-58.jpg" alt="Gateway-based client (2) " /> Gateway-based client (2)

Final thoughts Final thoughts

Creating a Spring-WS service • Create sample messages – Just XML • Create data Creating a Spring-WS service • Create sample messages – Just XML • Create data contract (XSD) – Infer from XML • Create operational contract (WSDL) – Infer from XSD • Create endpoints • Wire it up in Spring

Yeah, but…That’s a lot of <bean>s! • Mostly boilerplate • Can be “pre-declared” in Yeah, but…That’s a lot of s! • Mostly boilerplate • Can be “pre-declared” in a common Spring configuration file – Include in all service applications • Or rolled into a Maven 2 archetype • Maybe some Spring 2. 0 -style namespaces could simplify matters further.

What I didn’t talk about • • • Spring-WS and WS-Security Sending POX messages What I didn’t talk about • • • Spring-WS and WS-Security Sending POX messages RESTful Spring-WS (coming in 1. 1? ) JMS transports (coming in 1. 1) Mail transports (coming in 1. 1) WS-Addressing support (coming in 1. 1)

Recommended reading • Spring-WS homepage: – http: //www. springframework. org/spring-ws • Arjen Poutsma’s web-log Recommended reading • Spring-WS homepage: – http: //www. springframework. org/spring-ws • Arjen Poutsma’s web-log – http: //blog. springframework. com/arjen • Spring in Action, 2 E; Chapter 9

Q&A Don’t forget to turn in evals!!! http: //www. springinaction. com craig@habuma. com Q&A Don’t forget to turn in evals!!! http: //www. springinaction. com [email protected] com