Javaone 2010

2,207 views

Published on

Restful Web Services - JAX-RS and Spring Framework

1 Comment
4 Likes
Statistics
Notes
No Downloads
Views
Total views
2,207
On SlideShare
0
From Embeds
0
Number of Embeds
55
Actions
Shares
0
Downloads
0
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide

Javaone 2010

  1. 1. WHICH RESTFUL WEB SERVICESFRAMEWORK IS BETTER?JAX-RS OR SPRING FRAMEWORK Hien Luu
  2. 2. Agenda  REST Overview  Spring Framework & JAX-RS (Jersey)  Resource Identifier & Implementation  Resource Representation Support  Content Negotiation  Caching Support  Securing RESTful web services APIs  RESTful Client Library  Conclusion
  3. 3. REST Overview GET /v1/cu stomers/10 Accept: app 1 HTTP/1.1 lication/xm Client 1 l www.you.com .1 /101 HTTP/1 rs /v1/c ustome json Get cation/ cept : appli Ac Client 2 Two different resource representations
  4. 4. RESTful Web Services Framework  Spring Framework   Supports REST in 3.0   Extension to the MVC framework  JAX-RS   Java API for RESTful Web Services – JSR-311   Implementations   Jersey   RESTEasy – jboss   Restlet   Apache CXF
  5. 5. Resource Identifier & Implementation  Binding resource identifier to resource method  Root resource, sub-resource  Instantiation Model  Request data  Matrix parameter  Response, status code  Exception Handling
  6. 6. Resource Identifier & Implementation GET /customers/101 HTTP/1.1 JAX-RS Spring Framework @Path @RequestMapping@Path("/customers") @Controllerpublic class CustomerResource { @RequestMapping("/customers") public class CustomerResource { @GET @Path("{id}”) @RequestMapping("{id}”, public Customer getCustomer( method=RequestMethod.GET) @PathParam("id") int id) {} public Customer getCustomer( @PathVariable("id") int id) {}} }
  7. 7. Resource Identifier & Implementation  JAX-RS: Binding URI Regular Expression @Path("/customers") public class CustomerResource { @GET @Path("{id: d+}”) public Customer getCustomer( @PathParam("id") int id) {} }  Spring Framework: Ant-style expression @RequestMapping("/customers") public class CustomerResource { @RequestMapping(“/*/customer/{id}”) public Customer getCustomer(@PathVariable int id) { } }
  8. 8. Resource Identifier & Implementation JAX-RS@Path("/customers")public class CustomerResource { @POST @Consumes("application/xml") public Response createCustomer(Customer customer) {} @GET @Path("{id}") @Produces("application/xml") public Customer getCustomer(@PathParam("id") int id) {} @PUT @Path("{id}") @Consumes("application/xml") public Customer updateCustomer(@PathParam("id") int id, Customer customer) {}}
  9. 9. Resource Identifier & Implementation Spring@Controller@RequestMapping("/customers")public class CustomerResource { @RequestMapping(method=Request.POST, headers="Content-Type=application/xml") public String createCustomer(Customer customer) {} @RequestMapping(value=“/{id}”, method=Request.GET, headers=“Accept=application/xml”) public Customer getCustomer(@PathVariable int id) {} @RequestMapping(value=“/{id}”, method=Request.PUT, headers="Content-Type=application/xml") public Customer updateCustomer(@PathParam("id") int id, Customer customer) {}}
  10. 10. Resource Identifier & Implementation  JAX-RS Sub Resource Locator   Dynamically dispatch requests   Absent of request method designator: GET, POST, etc.   Return an object to handle HTTP request @Path("widgets") public class SubResourceLocatorResource { @Path("{region}") public SubResource dispatcher(@PathParam("region") String region) { return new SubResource(region); } }  Spring Framework - no sub resource locator
  11. 11. Resource Identifier & Implementation  Instantiation Model   JAX-RS   New resource instance per request (default)   Singleton (up to implementation)   Spring Framework   Singleton (default)
  12. 12. Resource Identifier & Implementation Request Data JAX-RS Spring Framework @QueryParam* @RequestParam* @FormParam* @RequestParam* @PathParam* @PathVariable* @CookieParam* @CookieValue* @HeaderParam* @RequestHeader* @MatrixParam* Not supported @Context • Can specify default value • Can specify require or not @DefaultValue • Can specify default valueJAX-RS allows above annotations on fields and setters with per-request scope resource
  13. 13. Resource Identifier & Implementation JAX-RS@GET@Path(“/foo/{id}”)public Response bar(@PathParm(“id”) int id, @QueryParam(“a”) @DefaultValue(“JavaOne”) String a, @FormParam(”b”) int b, @MatrixParam(“m”), @CookieParam(“token”) String token, @HeaderParam(“User-Agent”) String userAgent {} Spring@RequestMapping(value=“/foo/{id}”, method=Request.GET)public void bar(@PathVariable int id, @RequestParam(value=“a”, defaultValue=“JavaOne”) String a, @RequestParam(”b”, required=false) int b, @CookieValue(“token”) String token, @RequestHeader(“User-Agent”) String userAgent {}
  14. 14. Resource Identifier & Implementation  Context information - @Context   UriInfo – static and dynamic, per-request information   Application – resources   HttpHeaders – request header information   Request - precondition evaluation, representation variant   SecurityContext – security context of current request   Providers – look up provider instances @GET @Path("/{info: .+}") public Response getContextInfo(@Context Application app, @Context UriInfo uriInfo, @Context HttpHeaders headers, @Context Request request, @Context SecurityContext securityContext) { return Response.ok().build(); }
  15. 15. Resource Identifier & Implementation  Spring Framework   HttpServletRequest   Header   HttpServletResponse   Response   ApplicationContext @RequestMapping(”/info") public void getContextInfo(HttpServletRequest request, HttpServletResponse response) { // }
  16. 16. Resource Identifier & Implementation Resource Method Response JAX-RS Spring Framework void* void* Response* Any Java type GenericEntity* ResponseEntity<?> Any Java type* *null return status code 204 * Handle response itself
  17. 17. Resource Identifier & Implementation  JAX-RS   ResponseBuilder, Response, UriBuilder   Convenient for status code, setting headers @GET @Path(“/foo/{id}”) public Response bar(@PathParm(“id”) int id) { StringBuffer buf = new StringBuffer(); ResponseBuilder responseBuilder = Response.ok(buf.toString(), MediaType.TEXT_HTML_TYPE). location(URI.create("/foo”). lastModified(new Date()); return responseBuilder.build(); }
  18. 18. Resource Identifier & Implementation  Spring Framework   ResponseEntity<?>, HttpHeaders @ReuestMapping(value=“{id}”, method=RequestMethod=GET) public ResponseEntity<Customer> bar(@PathVariable int id) { Customer customer = …; HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setLocation(URI.create("/customers/" + id)); responseHeaders.setContentType(MediaType.APPLICATION_XML); return new ResponseEntity(customer, responseHeaders, HttpStatus.OK); }
  19. 19. Exception Handling - JAX-RS   Resource method   Canthrow checked or unchecked exception   WebApplicationException   Response – use directly if available   Can specify response code   Exception mapping interface   Mapping of an exception to specific Response@Provider   Total control the responsepublic class ExceptionMappingProvider implements ExceptionMapper<MyException>{ public Response toResponse(MyException exception) { return Response.status(Response.Status.FORBIDDEN). entity(exception.getMessage()).build(); }}
  20. 20. Exception Handling - JAX-RS @GET @Path(“{id}”) public Customer (@PathParm(“id”) int id) { Customer customer = getCustomer(id); if (customer == null) { throw new WebApplicationException(Response.Status.NOT_FOUND); } else { return customer; } }@GET@Path("/uncheckedException")public Response uncheckedException() { throw new MyException("just for fun");} @Provider public class ExMappingProvider implements ExceptionMapper<MyException> { public Response toResponse(MyException exc) { … } }
  21. 21. Exception Handling – Spring  Resource method   Canthrow checked or unchecked exception   @ResponseStatus – annotation on exception class   to control status code   Exception handler at resource class level (not global)   Can control status code and returned message   @ResponseBody   @ResponseStatus   Doesn’t support ResponseEntity   Default is 500 status code
  22. 22. Exception Handling – Spring@ResponseStatus(value=HttpStatus.FORBIDDEN)public class ForbiddenException extends RuntimeException { public ForbiddenException(String msg) { super(msg); }}@Controller@RequestMapping("/exceptions")public class ExceptionResource { @ResponseStatus(value=HttpStatus.NOT_FOUND) @ExceptionHandler(ResourceNotFoundException.class) public @ResponseBody String exceptionHandler1( ResourceNotFoundException ex1) { return ex1.getMessage(); } @RequestMapping("/resourceNotFoundException") public void resourceNotFoundException() { throw new ResourceNotFoundException("resource not found"); }}
  23. 23. Score Card Scores Feature JAX-RS Spring Resource URI 5.0 4.5 Sub resource 5.0 4.0 Request Data 5.0 4.8 Response, status code 5.0 4.5 Exception Handling 5.0 5.0
  24. 24. Resource Representation Support JAX-RS Spring erter Message ageConvXML BodyRea der HttpMess XML erter Message BodyWr HttpMessageConv iter Java POJO der eB odyRea HttpMe ssageC Messag onverte r iter HttpMeJSON sageB odyWr ssageCo nverter JSON Mes
  25. 25. Resource Representation Support Out-of-the-box Support JAX-RS Spring Frameworkbyte[] (*/*) byte[]String (*/*) StringInputStream (*/*) MultiValueMapReader (*/*) SourceFile (*/*) Class<T>Source (*/xml)JAXBElement (*/xml) Registered by defaultMultivalueMap (application/x-www-form-urlencoded)StreamingOutput (*/*)Class<T>
  26. 26. Resource Representation Support Content NegotiationGET http://<host>:<port>/customers/1Accept: application/xml;q=0.8, application/json;q=0.6 HTTP/1.1 200 OK Content-type: application/xml <customer id=“1”>….</customer> HTTP/1.1 200 OK Content-type: application/json {“customer” : { “id” : 1 …}} HTTP/1.1 406 Not Acceptable
  27. 27. Resource Representation Support JAX-RS Content-Type: application/xml @PUT @Path(”id}") @Consumes(“application/xml”) @Produces("application/xml”) public Customer updateCustomer(..) { .. Accept: application/xml } Spring@RequestMapping(value=“{id}”, method=RequetMethod.PUT, headers="Content-Type=application/xml”)public ResponseEntity<Customer> updateCustomer(..) { ..}
  28. 28. Resource Representation Support JAX-RS@GET@Path("{id}")@Produces({"application/xml", "application/json"})public Customer getCustomer(@PathParam("id") int id) { Customer customer = lookUpCustomer(id); return customer;} Spring@RequestMapping(value = "/{id}", method = RequestMethod.GET, headers=“Accept=application/xml,application/json”)public ResponseEntity<Customer> getCustomer(@PathVariable int id) { Customer customer = lookUpCustomer(id); return ResponseEntiry<Customer>(customer, HttpStatus.OK);}
  29. 29. Resource Representation Support JAX-RSpublic interface MessageBodyReader<T> { public interface MessageBodyWriter<T> { boolean isReadable(Class<?> type, ….); boolean isWriteable(Class<?> type, …); T readFrom(Class<?>, …); long getSize(T t, Class<?> type,…);} void writeTo(T t, Class<?> type,…) }@Provider @Providerpublic class MyMBR implements public class MyMBW implements MessageBodyReader<MyCustomerClass> { MessageBodyWriter<MyCustomerClass> { … …} }
  30. 30. Resource Representation Support Springpublic interface HttpMessageConverter<T> { boolean canRead(Class<?> clazz, MediaType mediaType); boolean canWrite(Class<?> clazz, MediaType mediaType); List<MediaType> getSupportedMediaTypes(); T read(Class<? extends T> clazz, HttpInputMessage inputMessage) void write(T t, MediaType contentType, HttpOutputMessage outputMessage)}public class MyHttpMessageConverter<MyCustomerClass> implements MessageBodyReader<MyCustomerClass> { …}
  31. 31. Resource Representation Support Spring - Content Negotiation Through URI Pattern GET http://<host>:<port>/customers/1.xml Request Resource GET http://<host>:<port>/customers/1.json ContentNegotiatingViewResolverapplication/json MappingJacksonJsonView JSON JSON - application/json XML - application/xmlapplication/xml MarshallingView XML
  32. 32. Resource Representation Support Advanced Content NegotiationGET http://<host>:<port>/customers/1Accept: application/xml;q=0.8, application/json;q=0.6Accept-Language: fr;q=1.0, en;p=0.5Accept-Encoding: gzip, deflatepublic class Variant { public Variant(MediaType mediaType, Locale locale, String encoding) { }} JAX-RSpublic interface Request { public Variant selectVariant(List<Variant> variants); ……}
  33. 33. Resource Representation Support Advanced Content Negotiation @GET @Path("{id}”) public Response getCustomer(@PathParam("id") int id, @Context Request request){ Variant.VariantBuilder vb = Variant.VariantBuilder.newInstance(); vb.mediaTypes(MediaType.APPLICATION_ATOM_XML_TYPE, MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE); vb.languages(Locale.CHINESE, Locale.FRANCE, Locale.ENGLISH); vb.encodings("deflate", "gzip"); List<Variant> variants = vb.add().build(); Variant matchedVariant = request.selectVariant(variants); Customer customer = lookUpCustomer(id); ResponseBuilder responseBuilder = Response.ok(customer); responseBuilder.type(matchedVariant.getMediaType()) .language(matchedVariant.getLanguage()) .header("Content-Encoding", matchedVariant.getEncoding()); return responseBuilder.build();}
  34. 34. Resource Representation Support Scores Feature JAX-RS Spring Request mapping 5.0 4.9 Resource representation 5.0 5.0 Custom data serialization 5.0 5.0 Content negotiation 5.0 5.0
  35. 35. Caching & Concurrency Caching & Concurrency Control HTTP Headers Cache Request Header Response HeaderValidation Cache-Control If-Modified-Since Last-Modified If-None-Match ETag If-Unmodified-Since Last-Modified If-Match EtagConcurrency Control
  36. 36. Caching & Concurrency Caching With DateGET /customers/1Accept: application/xml HTTP/1.1 200 OK Content-type: application/xml Cache-Control: private, no-store, max-age=600 Last-Modified: Sun, 22 August 2010 05:21 GMT <customer id=“1”>….</customer>GET /customers/1Accept: application/xmlIf-Modified-Since: Sun, 22 August 2010 05:21 EST HTTP/1.1 304 Not Modified
  37. 37. Caching & Concurrency Caching With ETagGET /customers/1Accept: application/xml HTTP/1.1 200 OK Content-type: application/xml Cache-Control: private, no-store, max-age=600 Etag: “123456789” <customer id=“1”>….</customer>GET /customers/1Accept: application/xmlIf-None-Match: “123456789” HTTP/1.1 304 Not Modified
  38. 38. Caching & Concurrency Conditional UpdatesGET /customers/1Accept: application/xml HTTP/1.1 200 OK Content-type: application/xml Cache-Control: private, no-store, max-age=600 Etag: “123456789” <customer id=“1”>….</customer>PUT /customers/1Accept: application/xmlIf-None-Match: “123456788” HTTP/1.1 412 Precondition Failed
  39. 39. Caching & Concurrency JAX-RS  CacheControl   Abstraction for Cache-Control header  EntityTag   Abstraction for entity tag  Request   evaluatePreconditions(EntityTagtag)   evaluatePreconditions(Date date)   Return non-null builder
  40. 40. Caching & Concurrency Spring  Servlet Filter   ShallowEtagHeaderFilter   Generate MD5 hash of the response   Automatically add Etag header   Detect If-None-Match and take action   Not flexible
  41. 41. Resource Representation Support Scores Feature JAX-RS Spring Caching 5.0 4.5 Concurrency Control 5.0 4.5
  42. 42. Securing RESTful web services APIs  Authentication   Basicauthentication – password is in Base64   Digest authentication – secure MD5 hashes  Authorization   Assign roles to users  API interact with servlet & J2EE   Setup in web.xml
  43. 43. Securing RESTful web services APIs JAX-RS Annotation Security@Path("/customers")@RolesAllowed(“ADMIN”, “CUSTOMER_REP”})public class CustomerResource { @RolesAllowed(“ADMIN”) @POST @Consumes("application/xml") public Response createCustomer(InputStream is) {} @PermitALL @GET @Path("{id}") @Produces("application/xml") public StreamingOutput getCustomer(@PathParam("id") int id) {}}
  44. 44. Securing RESTful web services APIs JAX-RS Programmatic Security@Path("/customers")public class CustomerResource { @POST @Consumes("application/xml") public Response createCustomer(Customer customer, @Context SecurityContext sc) { System.out.println(“User: “ + sc.getUserPrincipal().getName()); if (!sc.isUserInRole(“ADMIN”)) { // return 401 } }} Thin wrapper on HTTPServletRequest Security
  45. 45. Securing RESTful web services APIs Spring Programmatic Security@RequestMapping("/customers")public class CustomerResource { @RequestMapping(method = RequestMethod.POST, headers="Content-Type=application/xml”) public ResponseEntity<Customer> createCustomer(Customer customer, HttpServletRequest request) { if (!request.isUserInRole(“ADMIN”)) { // return 401 } }}
  46. 46. Resource Representation Support Scores Feature JAX-RS Spring Security 5.0 5.0
  47. 47. RESTful Client Library  Goals   Make it easy to work with Restful web services   Work at Java object level  Jersey Client   Notpart of JAX-RS   HTTPURLConnection, HTTPClient   Work with MessageBodyReader and MessageBodyWriter  Part of SpringFramework – RestTemplate   HTTPURLConnection,HTTPClient   Work with HttpMessageConverter
  48. 48. RESTful Client Library Scores Feature JAX-RS Spring RESTful Client Library 0 5.0 Each JAX-RS implementation provides their own client library
  49. 49. Summary JAX-RS ~ = Spring
  50. 50. Q &A

×