SlideShare a Scribd company logo
1 of 50
WHICH RESTFUL WEB SERVICES
FRAMEWORK IS BETTER?

JAX-RS OR SPRING FRAMEWORK


    Hien Luu
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
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
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
Resource Identifier & Implementation

  Binding resource identifier to resource method
  Root resource, sub-resource

  Instantiation Model

  Request data

  Matrix parameter

  Response, status code

  Exception Handling
Resource Identifier & Implementation

                            GET /customers/101 HTTP/1.1



             JAX-RS                       Spring Framework

             @Path                        @RequestMapping

@Path("/customers")                       @Controller
public 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) {}

}                                         }
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) {
         }
     }
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) {}
}
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) {}

}
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
Resource Identifier & Implementation

    Instantiation Model
       JAX-RS
         New  resource instance per request (default)
         Singleton (up to implementation)

       Spring   Framework
         Singleton   (default)
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 value

JAX-RS allows above annotations on fields and setters with per-request scope resource
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 {}
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();
     }
Resource Identifier & Implementation

    Spring Framework
       HttpServletRequest
           Header

       HttpServletResponse
           Response

       ApplicationContext


     @RequestMapping(”/info")
     public void getContextInfo(HttpServletRequest request,
           HttpServletResponse response) {

         //
     }
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
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();
 }
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);
 }
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 response
public class ExceptionMappingProvider implements ExceptionMapper<MyException>{
  public Response toResponse(MyException exception) {
     return Response.status(Response.Status.FORBIDDEN).
            entity(exception.getMessage()).build();
  }
}
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) {
                           …
                             }
                        }
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
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");
    }
}
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
Resource Representation Support

                       JAX-RS              Spring
                                                          erter
        Message                                    ageConv
XML            BodyRea
                         der              HttpMess                  XML

                                                        erter
          Message
                  BodyWr                 HttpMessageConv
                         iter
                                  Java
                                 POJO
                         der
               eB odyRea                  HttpMe
                                                ssageC
         Messag                                          onverte
                                                                r
                          iter           HttpMe
JSON
              sageB odyWr                      ssageCo
                                                      nverter
                                                                    JSON
           Mes
Resource Representation Support
                          Out-of-the-box Support

                 JAX-RS                          Spring Framework
byte[] (*/*)                          byte[]
String (*/*)                          String
InputStream (*/*)                     MultiValueMap
Reader (*/*)                          Source
File (*/*)                            Class<T>
Source (*/xml)
JAXBElement (*/xml)                   Registered by default
MultivalueMap (application/x-www-
form-urlencoded)
StreamingOutput (*/*)
Class<T>
Resource Representation Support
                            Content Negotiation


GET http://<host>:<port>/customers/1
Accept: 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
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(..) {
     ..
}
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);
}
Resource Representation Support
                                     JAX-RS

public 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                                     @Provider
public class MyMBR implements                 public class MyMBW implements
     MessageBodyReader<MyCustomerClass> {          MessageBodyWriter<MyCustomerClass>
                                              {
    …                                            …
}                                             }
Resource Representation Support
                                    Spring

public 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> {

    …
}
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




                                    ContentNegotiatingViewResolver



application/json
                   MappingJacksonJsonView
                                              JSON                   JSON - application/json
                                                                     XML - application/xml
application/xml
                       MarshallingView
                                               XML
Resource Representation Support
                        Advanced Content Negotiation

GET http://<host>:<port>/customers/1

Accept: application/xml;q=0.8, application/json;q=0.6
Accept-Language: fr;q=1.0, en;p=0.5
Accept-Encoding: gzip, deflate


public class Variant {
    public Variant(MediaType mediaType, Locale locale,
        String encoding) {
    }
}
                                                            JAX-RS
public interface Request {
    public Variant selectVariant(List<Variant> variants);
    ……
}
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();
}
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
Caching & Concurrency

                   Caching & Concurrency Control HTTP Headers


 Cache               Request Header            Response Header
Validation                              Cache-Control


              If-Modified-Since         Last-Modified
              If-None-Match             ETag


              If-Unmodified-Since       Last-Modified
              If-Match                  Etag
Concurrency
  Control
Caching & Concurrency
                                 Caching With Date

GET /customers/1
Accept: 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/1
Accept: application/xml
If-Modified-Since: Sun, 22 August 2010 05:21 EST


                                   HTTP/1.1 304 Not Modified
Caching & Concurrency
                             Caching With ETag

GET /customers/1
Accept: 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/1
Accept: application/xml
If-None-Match: “123456789”


                              HTTP/1.1 304 Not Modified
Caching & Concurrency
                             Conditional Updates

GET /customers/1
Accept: 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/1
Accept: application/xml
If-None-Match: “123456788”


                               HTTP/1.1 412 Precondition Failed
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
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
Resource Representation Support

                       Scores


           Feature        JAX-RS      Spring
 Caching                        5.0    4.5
 Concurrency Control            5.0    4.5
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
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) {}


}
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
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
         }
    }
}
Resource Representation Support

                      Scores


            Feature      JAX-RS      Spring
 Security                      5.0    5.0
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
RESTful Client Library

                              Scores


          Feature                   JAX-RS                 Spring
 RESTful Client Library                 0                   5.0



           Each JAX-RS implementation provides their own
                           client library
Summary


    JAX-RS   ~
             =   Spring
Q &A

More Related Content

What's hot

Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
b_kathir
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegap
yangdj
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpa
Staples
 

What's hot (18)

Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
 
L12: REST Service
L12: REST ServiceL12: REST Service
L12: REST Service
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Novelties in Java EE 7: JAX-RS 2.0 + IPT REST HATEOAS Polling Demo @ BGOUG Co...
Novelties in Java EE 7: JAX-RS 2.0 + IPT REST HATEOAS Polling Demo @ BGOUG Co...Novelties in Java EE 7: JAX-RS 2.0 + IPT REST HATEOAS Polling Demo @ BGOUG Co...
Novelties in Java EE 7: JAX-RS 2.0 + IPT REST HATEOAS Polling Demo @ BGOUG Co...
 
Jersey and JAX-RS
Jersey and JAX-RSJersey and JAX-RS
Jersey and JAX-RS
 
11-DWR-and-JQuery
11-DWR-and-JQuery11-DWR-and-JQuery
11-DWR-and-JQuery
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegap
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC Annotations
 
Spring Web Services
Spring Web ServicesSpring Web Services
Spring Web Services
 
SCWCD : The servlet container : CHAP : 4
SCWCD : The servlet container : CHAP : 4SCWCD : The servlet container : CHAP : 4
SCWCD : The servlet container : CHAP : 4
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpa
 
Slice: OpenJPA for Distributed Persistence
Slice: OpenJPA for Distributed PersistenceSlice: OpenJPA for Distributed Persistence
Slice: OpenJPA for Distributed Persistence
 
Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009
 
JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring Data
 
Kual Coeus KEW Technical Training
Kual Coeus KEW Technical TrainingKual Coeus KEW Technical Training
Kual Coeus KEW Technical Training
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 

Similar to Javaone 2010

RESTful services with JAXB and JPA
RESTful services with JAXB and JPARESTful services with JAXB and JPA
RESTful services with JAXB and JPA
Shaun Smith
 
RESTful Data Access Services with Java EE
RESTful Data Access Services with Java EERESTful Data Access Services with Java EE
RESTful Data Access Services with Java EE
Shaun Smith
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
Shreedhar Ganapathy
 

Similar to Javaone 2010 (20)

Ppt on web development and this has all details
Ppt on web development and this has all detailsPpt on web development and this has all details
Ppt on web development and this has all details
 
RESTful Web services using JAX-RS
RESTful Web services using JAX-RSRESTful Web services using JAX-RS
RESTful Web services using JAX-RS
 
JAX-RS 2.0 and OData
JAX-RS 2.0 and ODataJAX-RS 2.0 and OData
JAX-RS 2.0 and OData
 
Spark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RSSpark IT 2011 - Developing RESTful Web services with JAX-RS
Spark IT 2011 - Developing RESTful Web services with JAX-RS
 
Overview of RESTful web services
Overview of RESTful web servicesOverview of RESTful web services
Overview of RESTful web services
 
RESTing with JAX-RS
RESTing with JAX-RSRESTing with JAX-RS
RESTing with JAX-RS
 
CDI, Seam & RESTEasy: You haven't seen REST yet!
CDI, Seam & RESTEasy: You haven't seen REST yet!CDI, Seam & RESTEasy: You haven't seen REST yet!
CDI, Seam & RESTEasy: You haven't seen REST yet!
 
Jersey
JerseyJersey
Jersey
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
 
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX LondonJAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Spring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsSpring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topics
 
Android and REST
Android and RESTAndroid and REST
Android and REST
 
RESTful services with JAXB and JPA
RESTful services with JAXB and JPARESTful services with JAXB and JPA
RESTful services with JAXB and JPA
 
RESTful Data Access Services with Java EE
RESTful Data Access Services with Java EERESTful Data Access Services with Java EE
RESTful Data Access Services with Java EE
 
Brief Intro To Jax Rs
Brief Intro To Jax RsBrief Intro To Jax Rs
Brief Intro To Jax Rs
 
JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011JAX-RS JavaOne Hyderabad, India 2011
JAX-RS JavaOne Hyderabad, India 2011
 
ASP.NET WEB API
ASP.NET WEB APIASP.NET WEB API
ASP.NET WEB API
 

Javaone 2010

  • 1. WHICH RESTFUL WEB SERVICES FRAMEWORK IS BETTER? JAX-RS OR SPRING FRAMEWORK Hien Luu
  • 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. 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. 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. 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. Resource Identifier & Implementation GET /customers/101 HTTP/1.1 JAX-RS Spring Framework @Path @RequestMapping @Path("/customers") @Controller public 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. 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. 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. 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. 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. Resource Identifier & Implementation   Instantiation Model   JAX-RS   New resource instance per request (default)   Singleton (up to implementation)   Spring Framework   Singleton (default)
  • 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 value JAX-RS allows above annotations on fields and setters with per-request scope resource
  • 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. 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. Resource Identifier & Implementation   Spring Framework   HttpServletRequest   Header   HttpServletResponse   Response   ApplicationContext @RequestMapping(”/info") public void getContextInfo(HttpServletRequest request, HttpServletResponse response) { // }
  • 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. 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. 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. 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 response public class ExceptionMappingProvider implements ExceptionMapper<MyException>{ public Response toResponse(MyException exception) { return Response.status(Response.Status.FORBIDDEN). entity(exception.getMessage()).build(); } }
  • 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. 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. 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. 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. Resource Representation Support JAX-RS Spring erter Message ageConv XML BodyRea der HttpMess XML erter Message BodyWr HttpMessageConv iter Java POJO der eB odyRea HttpMe ssageC Messag onverte r iter HttpMe JSON sageB odyWr ssageCo nverter JSON Mes
  • 25. Resource Representation Support Out-of-the-box Support JAX-RS Spring Framework byte[] (*/*) byte[] String (*/*) String InputStream (*/*) MultiValueMap Reader (*/*) Source File (*/*) Class<T> Source (*/xml) JAXBElement (*/xml) Registered by default MultivalueMap (application/x-www- form-urlencoded) StreamingOutput (*/*) Class<T>
  • 26. Resource Representation Support Content Negotiation GET http://<host>:<port>/customers/1 Accept: 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. 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. 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. Resource Representation Support JAX-RS public 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 @Provider public class MyMBR implements public class MyMBW implements MessageBodyReader<MyCustomerClass> { MessageBodyWriter<MyCustomerClass> { … … } }
  • 30. Resource Representation Support Spring public 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. 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 ContentNegotiatingViewResolver application/json MappingJacksonJsonView JSON JSON - application/json XML - application/xml application/xml MarshallingView XML
  • 32. Resource Representation Support Advanced Content Negotiation GET http://<host>:<port>/customers/1 Accept: application/xml;q=0.8, application/json;q=0.6 Accept-Language: fr;q=1.0, en;p=0.5 Accept-Encoding: gzip, deflate public class Variant { public Variant(MediaType mediaType, Locale locale, String encoding) { } } JAX-RS public interface Request { public Variant selectVariant(List<Variant> variants); …… }
  • 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. 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. Caching & Concurrency Caching & Concurrency Control HTTP Headers Cache Request Header Response Header Validation Cache-Control If-Modified-Since Last-Modified If-None-Match ETag If-Unmodified-Since Last-Modified If-Match Etag Concurrency Control
  • 36. Caching & Concurrency Caching With Date GET /customers/1 Accept: 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/1 Accept: application/xml If-Modified-Since: Sun, 22 August 2010 05:21 EST HTTP/1.1 304 Not Modified
  • 37. Caching & Concurrency Caching With ETag GET /customers/1 Accept: 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/1 Accept: application/xml If-None-Match: “123456789” HTTP/1.1 304 Not Modified
  • 38. Caching & Concurrency Conditional Updates GET /customers/1 Accept: 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/1 Accept: application/xml If-None-Match: “123456788” HTTP/1.1 412 Precondition Failed
  • 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. 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. Resource Representation Support Scores Feature JAX-RS Spring Caching 5.0 4.5 Concurrency Control 5.0 4.5
  • 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. 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. 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. 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. Resource Representation Support Scores Feature JAX-RS Spring Security 5.0 5.0
  • 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. RESTful Client Library Scores Feature JAX-RS Spring RESTful Client Library 0 5.0 Each JAX-RS implementation provides their own client library
  • 49. Summary JAX-RS ~ = Spring
  • 50. Q &A