Spring Web Services: SOAP vs. REST
-
Upload
sam-brannen -
Category
Documents
-
view
23.005 -
download
3
description
Transcript of Spring Web Services: SOAP vs. REST
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