spring web services: soap vs. rest

Post on 10-May-2015

23.005 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

SOAP Web Services have a well established role in the enterprise, but aside from the many benefits of the WS-* standards, SOAP and XML also carry additional baggage for developers. Consequently, REST Web Services are gaining tremendous popularity within the developer community. This session will begin by comparing and contrasting the basic concepts of both SOAP and REST Web Services. Building on that foundation, Sam Brannen will show attendees how to implement SOAP-based applications using Spring-WS 2.0. He will then demonstrate how to build a similar REST-ful application using Spring MVC 3.0. The session will conclude with an in-depth look at both server-side and client-side development as well as efficient integration testing of Web Services using the Spring Framework.

TRANSCRIPT

Spring Web Services:SOAP vs. REST

SamBrannenSwi+mindGmbH

SpeakerProfile

•  SeniorSo+wareConsultant–Swi+mindGmbH•  Javadeveloperwith13+years'experience•  SpringFrameworkCoreDeveloper– AuthoroftheSpringTestContextFramework

•  PreviousSpringSourcedmServer™developer•  RegularspeakeratconferencesonSpring,dmServer,Java,OSGi,andtesOng

•  LeadauthorofSpringinaNutshell;chieftechnicalreviewerforSpringRecipes

Agenda

•  WebServicesConcepts•  SpringEventsApplicaOon•  Spring‐WS

•  SpringREST•  Server‐side•  Client‐side•  Q&A

WebServices

Concepts

•  Client/ServerarchitectureovertheWeb– ServerexposesServices– ClientsendsaRequesttotheServer•  foraspecificexposedService•  withaPayloadtobeprocessedbytheService

– ServiceprocessestheRequestandreturnsaResponse

MarshallingandUnmarshalling

•  Marshalling:Objectexternalformat•  Unmarshalling:externalformatObject

•  arequestorresponsecontainsapayload– o+enintheformofanXMLdocument– mayalsobebinary,JSON,etc.

•  applicaOoncodehasitsowndomainmodel– maynotmapdirectlytoformatofpayload

SpringEventsApplica?on

IntroducingSpringEvents

•  SimplePOJOdomainmodel:Event•  TransacOonalservicelayer•  Hibernaterepositorylayer– Withanin‐memoryHSQLdatabase

•  Spring@MVCpresentaOonlayer– RESTful@Controller

•  Spring‐WS@Endpoint

SpringEventsApplicaOon

Demo

SOAPWebServices

WhatisSpring‐WS?

SpringWebServicesaimstofacilitatecontract‐firstSOAPservicedevelopment,allowingforthecreaAonofflexiblewebservicesusingoneofthemanywaystomanipulateXMLpayloads.(Spring‐WSWebsite)

WhatisSOAP?

•  SimpleObjectAccessProtocol– ProtocolforexchanginginformaOonviaWebServices

– UsesXMLasitsmessageformat– TypicallyoverHTTP

•  Structure– Envelope– Header– Body(a.k.a.,payload)– Documentliteral

ContractLast

•  DefineAPIinprogramminglanguage(e.g.,Java)

•  UsetoolstogenerateXSDsandWSDLfromcode

•  Pros–  easy,no‐brainerfordevelopers

•  Cons–  horriblyfragile–  anychangetocodebreakspreviouslypublishedcontract

–  clientsmustbeupdated

ContractFirst

•  DefinepublicAPItoservicesviaXSDschemasfirst– onerequestandresponseperexposedservice– generateWSDLfromXSDsusingconvenOonsforporttypes,etc.•  potenOallyauto‐generated

– generateJavacodefromXSDs(e.g.,JAXB2)– createJavamappingcodemanually– oruseXPath,etc.toparseXMLdirectly

RESTWebServices

WhatisSpringREST?

•  RESTfulWebServicesbuiltontopofSpring@MVC

•  CombinesnicelywithexisOng@MVCcode

•  LowlearningcurvefordevelopersfamiliarwithSpring@MVC

•  SupportsmulOplemarshallingtechnologiessuitableforwebapplicaOons(e.g.,JSON)

•  SpringREST!=JAX‐RS

WhatisREST?

•  REpresentaOonalStateTransfer•  HTTPProtocol– Standard– Ubiquitous– Scalable

•  Stateless•  Focusesonresources– NounsandVerbs

Nouns,Verbs,&Errors

•  Nouns– Resourcesthatyouwanttointeractwith

•  Verbs– Whatyoucandowitharesource•  POST:createnewresource•  GET:getsingleresourceoralistofresources•  PUT:updateresource•  DELETE:deleteresource

•  Errorhandling– StandardHTTPresponsecodes

RESTfulURLs

•  POST– hip://example.com/events

•  GET– hip://example.com/events– hip://example.com/events/1

•  PUT– hip://example.com/events/1

•  DELETE– hip://example.com/events/1

Server‐side

Spring‐WSontheServer

•  Bootstrappedinweb.xmlwithMessageDispatcherServlet

•  <sws:annotaOon‐driven/>enables@Endpointmappings(ala@Controller)

•  @PayloadRootmapshandlermethods

•  @RequestPayloadmapspayloadtomethodparameter

•  @ResponsePayloadmapsreturnvaluetoresponsepayload

GetEventEndpoint(1/2)@Endpointpublic class GetEventEndpoint {

private static final String NAMESPACE_URI = "http://example.com/schemas";

private final EventService eventService;

@Autowired public GetEventEndpoint(EventService eventService) { this.eventService = eventService; }

GetEventEndpoint(2/2)@PayloadRoot(localPart="GetEventRequest", namespace=NAMESPACE_URI)@ResponsePayloadpublic GetEventResponse getEvent( @RequestPayload GetEventRequest request) throws Exception {

Event event = eventService.findById(request.getId().longValue());

return toGetEventResponse(event);}

SpringRESTontheServer

•  RESTWebServiceendpointsare@Controllers– @RequestMapping:mapstohandlermethods– @RequestBody:payloadofrequest– @ResponseBody:payloadofresponse– @ResponseStatus:setHTTPresponsecode– @PathVariableandUriTemplate•  FormappingandcreaOngRESTfulURIs

•  AutomaOcmarshallingofpayloads•  ContentnegoOaOon

EventController(1/4)@RequestMapping("/events")@Controllerpublic class EventController {

protected final EventService eventService;

@Autowired public EventController(EventService eventService) { this.eventService = eventService; }

EventController(2/4)@RequestMapping(method = GET)@ResponseBodypublic List<Event> retrieveAllEvents() { return eventService.findAllEvents();}

@RequestMapping(value = "/{id}", method = GET)@ResponseBodypublic Event retrieveEvent(@PathVariable Long id) { return eventService.findById(id);}

EventController(3/4)@RequestMapping(method = POST)@ResponseStatus(HttpStatus.CREATED)public void createEvent(@RequestBody Event postedEvent, HttpServletRequest request, HttpServletResponse response) {

Event savedEvent = eventService.save(postedEvent);

String newLocation = buildNewLocation(request, savedEvent.getId());

response.setHeader("Location", newLocation);}

EventController(4/4)@RequestMapping(value = "/{id}", method = DELETE)@ResponseStatus(HttpStatus.NO_CONTENT)public void deleteEvent(@PathVariable Long id) { eventService.deleteById(id);}

private String buildNewLocation(HttpServletRequest request, Long id) {

String url = request.getRequestURL() .append("/{id}").toString();

UriTemplate uriTemplate = new UriTemplate(url); return uriTemplate.expand(id).toASCIIString();}

HiddenHipMethodFilter

•  WebbrowserstypicallyonlysupportGETandPOST

•  HiddenHipMethodFilter– providessupportforPUTandDELETErequestsfromwebbrowsers

–  transparentlyconvertsPOSTrequestswithhidden_methodparameter

•  Configuredinweb.xml

•  CanbeusedinconjuncOonwithSpring’sJSPformtaglibrary

URITemplatesinJSPs

•  Usethe<spring>taglibrarytoconstructdynamicURItemplatesinJSPs

•  SimilartotheJSPcoretaglibrarysupportforbuildingURLswithparameters

<spring:urlvar="jsonUrl"value="/rest/events/{id}">

<spring:paramname="id"value="${event.id}"/></spring:url>

Client‐side

WebServiceTemplate

•  InteractwithSOAPWebServicesasaclient•  SupportscallbacksaswellasautomaOcmarshallingandunmarshallingofpayloads– sendAndReceive(…)– marshalSendAndReceive(…)

– etc.

EventsSoapClientTest(1/2)@RunWith(SpringJUnit4ClassRunner.class)@ContextConfigurationpublic class EventsSoapClientTest {

@Autowired private WebServiceTemplate webServiceTemplate;

<oxm:jaxb2-marshaller id="marshaller” contextPath="com.swiftmind.samples.events.web.schema" />

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate” p:marshaller-ref="marshaller" p:unmarshaller-ref="marshaller" />

EventsSoapClientTest(2/2)@Testpublic void getEventRequest() {

String url = "http://localhost:8080/spring/soap";

GetEventRequest request = new GetEventRequest(); request.setId(BigInteger.valueOf(5L));

GetEventResponse response = (GetEventResponse) webServiceTemplate.marshalSendAndReceive(url, request);

assertNotNull(response); assertEquals("Spring I/O in Madrid", response.getEventData().getDescription()); }

RestTemplate

•  InteractwithanyRESTWebServices– notlimitedtoSpringRESTservices

•  SupportsURItemplatesandautomaOcmarshallingandunmarshallingofpayloads– postForLocaOon(…)– postForObject(…)– getForObject(…)– delete(…)– put(…)– etc.

EventsRestClient(1/3)public class EventsRestClient {

private final RestTemplate restTemplate = new RestTemplate(); private String url;

public URI createEvent(String name) { Event event = new Event(); event.setName(name);

return restTemplate.postForLocation(url, event); }

EventsRestClient(2/3)public void deleteEventByLocation(URI location) { restTemplate.delete(location);}

public void deleteEventById(Long id) { String deletionUrl = url + "/{id}";

restTemplate.delete(deletionUrl, id);}

EventsRestClient(3/3)public void retrieveEvent(URI location) { Event event = restTemplate.getForObject(location, Event.class);}

public void retrieveAllEvents() { Event[] events = restTemplate.getForObject(url, Event[].class);}

SpringSOAPWebServices

Demo

SpringRESTWebServices

Demo

FurtherResources

•  SpringFramework–  IncludingSpringREST–  hip://springframework.org

•  Spring‐WS–  hip://staOc.springsource.org/spring‐ws/sites/2.0/

•  GenerateXSDfromXML–  hip://bit.ly/fLI1Bt

Q&A

SamBrannen

sam.brannen[at]swi+mind[dot]com

hip://www.swi+mind.com

hip://twiier.com/sam_brannen

“SpringinaNutshell” hip://oreilly.com/catalog/9780596801946 availablefromO’Reillyin2011

top related