Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
REST Carol McDonald, Java Architect
Agenda REST Primer RESTful Design and API Elements Building a Simple Service Status Q & A
REpresentational State Transfer Get  http://www.depot.com/parts Response XML data = REpresentational State Transfer   The  URL  identifies the  resource HTTP GET   method  operates on the resource html  page is transferred  to the browser REpresentational State transfer The page ( application   state ) is stored on the  client  (browser) Click on the link (resource) in page ( hypermedia ) New state transfer occurs
REST architecture for the Web  Web platforms Addressable Resources Web Container Addressable Resources Web Container
REST Tenets Resources   ( nouns ) Identified  by a  URI , For example: http://www.parts-depot.com/parts Methods   ( verbs )  to manipulate the nouns Small fixed set: GET, PUT, POST, DELETE Read, Update, Create, Delete Representation  of the Resource  data and state  transferred between client and server XML, JSON ... Use  verbs  to  exchange  application state and  representation
HTTP Example Request GET   /music/artists/beatles/recordings  HTTP/1.1 Host: media.example.com Accept: application/xml Response HTTP/1.1 200 OK Date: Tue, 08 May 2007 16:41:58 GMT Server: Apache/1.3.6 Content-Type: application/xml; charset=UTF-8 <?xml version=&quot;1.0&quot;?> <recordings xmlns=&quot;…&quot;> <recording>…</recording> … </recordings> Method Resource  Representation State transfer
REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications http://www.infoq.com/articles/rest-introduction Uniform Interface
Give Every Thing an Id  http://company.com/customers/123456 Resource Collection name Primary key http://company.com/customers/123456/orders/12 http://example.com/orders/2007/11 http://example.com/products?color=green URI is the id, Every resource has a URI URIs identify : items, collections of items, virtual and physical objects, or computation results.
REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications http://www.infoq.com/articles/rest-introduction Uniform Interface
Use Standard  HTTP Methods: GET  = Read GET to retrieve information Should  not modify  anything  Cacheable Example GET /store/customers/123456
Use Standard  HTTP Methods: POST  = Create POST to  add new  information add the entity ,  append  to the container resource POST /store/customers <customer> <name>carol</name> </customer> Response HTTP/1.1 201 Created Location: http://store/customers/789
Use Standard  HTTP Methods: PUT = Update PUT to  update  information Full entity  create/replace  used when you know the “ id ” Example PUT /store/customers/123456 <customer> <name>jane</name> </customer>
Use Standard  HTTP Methods: DELETE Remove (logical) an entity Example DELETE /store/customers/123456
Use Standard  Methods:  http://www.infoq.com/articles/rest-introduction Order Customer Mgmt Example
Use Standard  Methods: /orders GET - list all orders POST - submit a new order /orders/{order-id} GET - get an order representation PUT - update an order DELETE - cancel an order /orders/average-sale GET - calculate average sale /customers GET - list all customers POST - create a new customer /customers/{cust-id} GET - get a customer representation DELETE- remove a customer /customers/{cust-id}/orders GET - get the orders of a customer Order Customer Mgmt Example http://www.infoq.com/articles/rest-introduction
Use Standard  HTTP Methods HTTP Get, Head Should  not modify  anything  Cache-able With Correct use of  Last-Modified  and  ETag Idempotency:  PUT, DELETE, GET, HEAD can be  repeated  and the  results are the same
REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications * Inspired by Stefan Tilkov:  http://www.innoq.com/blog/st/presentations/2008/2008-03-13-REST-Intro--QCon-London.pdf
Link Things Together Representations contain links to other resources Service provides  links in response  to the Client  Enables client to move the application from one  state  to the  next  by following a  link Representations  contain   links   to other  resources: <prop self=&quot; http://example.com/orders/101230 &quot;> <customer ref=&quot; http://example.com/customers/bar &quot;> <product ref=&quot; http://example.com/products/21034 &quot;/> <amount value=&quot;1&quot;/> </order>
Link Things Together Representations  contain  links  to other  resources Put a service in different states by following links and filling in forms “ Hypermedia as the engine of application state” HTML, XML, JSON, N3 can all be Hypermedia  Client is in charge Service  offers  potential  states Service does not impose state transition order
REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications * Inspired by Stefan Tilkov:  http://www.innoq.com/blog/st/presentations/2008/2008-03-13-REST-Intro--QCon-London.pdf
Multiple Representations Offer data in a variety of formats, for different needs XML JSON (X)HTML Support  content negotiation Accept header GET /foo Accept:  application/json URI-based GET / foo.json
content negotiation Multiple Representations Content-type HTTP header Accept HTTP header Request GET   /music/artists/beatles/recordings  HTTP/1.1 Host: media.example.com Accept : application/xml Response HTTP/1.1 200 OK Date: Tue, 08 May 2007 16:41:58 GMT Server: Apache/1.3.6 Content-Type : application/xml; charset=UTF-8 <?xml version=&quot;1.0&quot;?> <recordings xmlns=&quot;…&quot;> <recording>…</recording> … </recordings> Format  Representation
REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications * Inspired by Stefan Tilkov:  http://www.innoq.com/blog/st/presentations/2008/2008-03-13-REST-Intro--QCon-London.pdf
Stateless Communications HTTP protocol is  stateless Everything  required to process  a  request   contained in  the  request No client session on the server Eliminates  many  failure  conditions application  state kept on  Client   Service responsible for  resource  state
Common Patterns: Container, Item Server in control of URI  Container  – a  collection  of items List catalog items:  GET /catalog/items Add  item to container:  POST  /catalog/items   with item in request URI of item returned in HTTP response header e.g.  http://host/ catalog/items/1 Update  item:  PUT  /catalog/items/1   with updated item in request Good example: Atom Publishing Protocol
Common Patterns: Map, Key, Value Client in control of URI   List  key-value pairs :  GET /map Put  new value to map:  PUT  /map/{key}   with entry in request e.g.  PUT /map/dir/contents.xml Read value:  GET /map/{key} Update value:  PUT /map/{key}   with updated value in request Remove value:  DELETE /map/{key} Good example: Amazon S3
Key Benefits Server side Uniform  Interface Cacheable Scalable Easy  failover Client side Easy to experiment in  browser Broad programming  language support Choice of  data formats bookmarkable
Agenda REST Primer RESTful Design and API Elements with JAX-RS Building a Simple Service Status Q & A
JAX-RS: Clear mapping to REST concepts High level, Declarative Uses  @ annotation  in POJOs Jersey – reference implementation of JSR 311 Download it from  http://jersey.dev.java.net Comes with Glassfish, Java EE 6 Tools support in NetBeans Four other open source implementations: Apache CXF JBoss RESTEasy Restlet Triaxrs
Give Everything an ID “Thing” == resource class POJO, No required interfaces ID provided by  @Path  annotation Relative to deployment context Annotate  class  or “ sub-resource  locator” method http://host/ctx/orders/12 http://host/ctx/orders/12/customer @Path( &quot;orders/{id}&quot;) public class OrderResource { @Path(&quot;customer&quot;) CustomerResource getCustomer(...) {...} }
Use Standard Methods Annotate resource class methods with standard method @GET ,  @PUT ,  @POST ,  @DELETE ,  @HEAD annotations on  parameters  specify mapping from  request  data Return  value mapped to http  response @Path(&quot;orders/ {order_id} &quot;) public class OrderResource { @GET Order getOrder( @PathParam (&quot; order_id &quot;) String id) { ... } }
Multiple Representations Static and dynamic content negotiation Annotate methods or classes  @Produces  matches  Accepts  header @Consumes  matches  Content-Type  header @GET @Consumes(&quot;application/json&quot;) @Produces({&quot;application/xml&quot;,&quot;application/json&quot;}) String getOrder(@PathParam(&quot;order_id&quot;) String id) { ... }
Multiple Representations : JAX-RS consuming Annotated  method  parameters  extract client request information @PathParam  extracts information from the  request URI @QueryParam  extracts information from the  request URI query  parameters http://host/catalog/items/ 123 http://host/catalog/items/ ?start=0
Multiple Representations : JAX-RS consuming http://host/catalog/items/?start=0 http://host/catalog/items/123 @Path(&quot;/items/&quot;) @ConsumeMime(“application/xml”) public class ItemsResource { @GET ItemsConverter get( @QueryParam (&quot;start&quot;)   int  start ) { ... } @Path( &quot;{id}/&quot; ) ItemResource getItemResource( @PathParam (&quot;id&quot;)Long  id ){ ... }  }
Multiple Representations : Supported Types JAX-RS can automatically (un)-marshall between  HTTP request/response  and  Java  types “Out-of-the-box” support for the following text/xml, application/xml, application/json –  JAXB class */*  –   byte[] text/*  –  String application/x-www-form-urlencoded  - MultivaluedMap<String, String> response
Multiple Representations @Post @ConsumeMime(“application/x-www-form-urlencoded”) @ProduceMime(“application/xml”) public  JAXBClass  updateEmployee( MultivalueMap<String, String>  form) { ... Converted to a map for accessing form's field converted to  XML
Multiple Representations : producing a response Use  Response  class to  build “created”response @Path(“/items”) class Items { @POST   @ProduceMime(“application/xml”)  Response  create(Ent e) {  // persist the new entry, create  URI return  Response.created ( uriInfo.getAbsolutePath(). resolve(uri+&quot;/&quot;)).build(); } }
Uniform interface: HTTP request and response C: POST /items HTTP/1.1 C: Host: host.com C: Content-Type: application/xml C: Content-Length: 35 C:  C: <item><name>dog</name></item> S: HTTP/1.1  201   Created S:  Location: http://host.com/employees/1234 S: Content-Length: 0
Response Codes and Custom Responses JAX-RS returns default response codes GET returns 200 OK  PUT returns 201 CREATED See  http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 200 OK 201 Created 202 Accepted 203 Non-Authoritative Information 204 No Content 205 Reset Content 206 Partial Content 207 Multi-Status 226 IM Used . . .
JAX-RS provides Response class @PUT public  Response  putUser( @PathParam(“id”) int id) { if (!id.equals(userid) ) return  Response .status(409).entity( &quot;userids differ&quot;).build(); JAX-RS provides  Response  class: to specify response codes,  to add onto the response can construct more sophisticated return result Can build responses for redirects, errors, ok, setting headers, etc
WebApplicationException Example @GET public  Employee  getEmployee( @PathParam(“id”) int id) { if (!doesEmployeeExist(id))   throw new  WebApplicationException( new Throwable(&quot;Resource for &quot; + uriInfo.getAbsolutePath() + &quot; does not exist.&quot;), 404); Response: HTTP Status 404 - Use it when the method has a return type Simple error indicator
Link Things Together UriInfo  provides  information  about the  request URI  and the route to the resource UriBuilder  provides facilities to easily  build  URIs for resources @Context  UriInfo   info ; OrderResource r = ... UriBuilder  b =  info.getBaseUriBuilder(); URI u =  b.path(OrderResource.class).build(r.id);
Statelessness: JAX-RS The default  component lifecycle  is  per-request A  new instance  created for every  request Reduces concurrency issues HTTP session  life-cycle is not supported On server side Developer must model state  As  resource state  in the  representations
Agenda REST Primer RESTful Design and API Elements Building a Simple Service   Deployment Options Status
Example RESTful Catalog
Example RESTful Catalog http://weblogs.java.net/blog/caroljmcdonald/archive/2008/08/a_restful_pet_c.html
Example RESTful Catalog Service  Catalog Database Web container (GlassFish™) + REST API  Browser (Firefox) HTTP
URIs  and  Methods: /items GET - list all items POST – add item to catalog /items/{id} GET - get an item representation PUT - update an item DELETE – remove an item  Item Catalog Example http://www.infoq.com/articles/rest-introduction
Methods  Java method name is not significant The @HTTP method is the method @Path(“/items”) class ItemsResource { @GET  Items get() { ... } @POST  Response create(Item) { ... } } class ItemResource { @GET  Item get(...) { ... } @PUT  void update(...) { ... } @DELETE  void delete(...) { ... } }
RESTful Catalog  Dojo client, JAX-RS, JAXB, JPA DB Registration Application JAX-RS class Dojo client JAXB class Entity Class ItemsConverter Item ItemsResource
Entity Classes Use JPA to map/retrieve data from the database as entities expose entities as RESTful resources  entity = resource identified by URL http://host/catalog/items/123 public class Item {    int id;   String name;    String descr;   String url; } @Entity @Id Item ID NAME DESC URL
Converter Classes JAXB  to convert the domain objects (JPA  entities ) into  XML and/or JSON . DB JAX-RS class Dojo client JAXB class Entity Class ItemsConverter Item ItemsResource
ItemConverter JAXB annotated  @XmlRootElement(name = &quot;item&quot;) public class ItemConverter { private Item entity; private URI uri; @XmlAttribute public URI getUri() { return uri; } @XmlElement public Long getId() { return (expandLevel > 0) ? entity.getId() : null; } ...   }
XML <item  uri=&quot;http://localhost/Web/resources/items/1/&quot; > <description> black cat is nice</description> <id>1</id> <imagethumburl>/images/anth.jpg</imagethumburl> <name>not Friendly Cat</name> <price>307.10</price> <productid>feline01</productid> </item>
JSON { &quot;@uri&quot;:&quot;http://host/catalog/resources/items/1/&quot;, &quot;name&quot;:&quot;Friendly Cat&quot;, &quot;description&quot;:&quot;This black and white colored cat is super friendly.&quot;,  &quot;id&quot;:&quot;1&quot;, &quot;imageurl&quot;:&quot; http://localhost:8080/CatalogService/images/anthony.jpg &quot; }
ItemsConverter JAXB annotated  @XmlRootElement(name = &quot;items&quot;) public class ItemsConverter { private Collection<ItemConverter> items; private URI uri; @XmlAttribute public URI getUri() { return uri; } @XmlElement public Collection<ItemConverter> getItem() { ... return items; } }
XML <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <items uri=&quot;http://localhost/Web/resources/items/&quot;> <item  uri=&quot;http://localhost/Web/resources/items/1/&quot; > <description> black cat is nice</description> <id>1</id> <imagethumburl>/images/anth.jpg</imagethumburl> <name>not Friendly Cat</name> <price>307.10</price> <productid>feline01</productid> </item> <item  . . . </item> </items>
JSON { &quot;@uri&quot;:&quot;http://host/catalog/resources/items/&quot;, &quot; item &quot;:[ {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/1/&quot;, &quot;name&quot;:&quot;Friendly Cat&quot;, &quot;description&quot;:&quot;This black and white colored cat is super friendly.&quot;,  &quot;id&quot;:&quot;1&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/anthony.jpg&quot;}, {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/2/&quot;, &quot;name&quot;:&quot;Fluffy Cat&quot;, &quot;description&quot;:&quot;A great pet for a hair stylist! &quot;id&quot;:&quot;2&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/bailey.jpg&quot;} ] }
Resource Classes Items Resource  retrieves updates a  collection of Item entities /items  – URI for a list of  Items Item resource  retrieves or updates one Item  entity /item/1  – URI for item  1 DB JAX-RS class Dojo client JAXB class Entity Class ItemsConverter Item ItemsResource
Get Items  @Path(&quot;/items/&quot;) public class ItemsResource { @Context protected UriInfo uriInfo; @GET @Produces (&quot;application/json&quot;) public  ItemsConverter  get(){ return new ItemsConverter( getEntities(), uriInfo.getAbsolutePath()); } Performs JPA Query, returns list of entities  JAXB class responds with JSON responds to the URI  http://host/catalog/items/ responds to HTTP GET
Get  Item @Path(&quot;/items/&quot;) public class  ItemsResource  { @Path(&quot;{id}/&quot;) public ItemResource getItemResource( @PathParam (&quot;id&quot;) Long id) { return new  ItemResource (id, context); } } public class  ItemResource  {  @GET @Produces ( &quot;application/json&quot;) public ItemConverter get() { return new ItemConverter(getEntity(), context.getAbsolutePath(), expandLevel); } JAXB class http://host/catalog/items/123
Dojo Client Use dojo.xhrGet  to make HTTP method call to catalog service to get JSON items data: {&quot; items &quot;: {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/&quot;, &quot; item &quot;:[ {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/1/&quot;, &quot;name&quot;:&quot;Friendly Cat&quot;, &quot;description&quot;:&quot;This black and white colored cat is super friendly.&quot;,  &quot;id&quot;:&quot;1&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/anthony.jpg&quot;}, {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/2/&quot;, &quot;name&quot;:&quot;Fluffy Cat&quot;, &quot;description&quot;:&quot;A great pet for a hair stylist! &quot;id&quot;:&quot;2&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/bailey.jpg&quot;} ] } }
Example RESTful Catalog
Dojo client  index.html <button dojoType=&quot;dijit.form.Button&quot; onclick=&quot; next &quot;> Next </button> <div id=&quot;grid&quot;  dojoType =&quot; dojox.Grid &quot;  model =&quot; model &quot; structure =&quot; layout &quot; autoWidth=&quot;true&quot; > http://weblogs.java.net/blog/caroljmcdonald/archive/2008/08/a_restful_pet_c.html Grid widget
Dojo client.js   formatImage  = function(value) { if (!value) return '&nbsp;';  return &quot;<img src='&quot; + value + &quot;'/>&quot;;  }; // Data Grid layout // A grid view is a group of columns var view1 = { cells: [ [ {name: 'Name', field: &quot;name&quot;}, {name: 'Description', field: &quot;description&quot;}, {name: 'Photo',field: &quot;imagethumburl&quot;,  formatter:  formatImage , }, {name: 'Price',field: &quot;price&quot;} ] ] }; // a grid layout is an array of views. var  layout  = [ view1 ]; // the model= collection of objects to be displayed in the grid model  = new dojox.grid.data.Objects(null,null);
RESTful Pet Catalog Web Service  http://petstore/catalog/resources/items/ HTTP  GET {&quot;url&quot;:&quot;http://store/catalog/item1&quot;, {&quot;url&quot;:&quot;http://store/catalog/item2&quot;} Response JSON slide urls Server Client  Addressable Resources Web Container
Dojo client.js   // make request to the items web service function  loadTable (page){ start = page * batchSize; var  targetURL  = &quot;resources/items/?start=&quot;+   encodeURIComponent(start); dojo.xhrGet ({ url:  targetURL , handleAs: &quot;json&quot;, load:  handleResponse , error: handleError }); } // Process the response from the items web service function  handleResponse ( responseObject , ioArgs){ // set the model object with the returned items list  model .setData( responseObject.items.item ); } function  next()  { page =page + 1; loadTable (page); } Performs HTTP GET on url  catalog/items
Client  & WADL NetBeans IDE can generate JavaScript client stubs from a  WADL  or  projects  containing RESTful resources NetBeans IDE exposes popular SaaS services using WADLs and can generate Java code to access them Learn more at  https://wadl.dev.java.net/ Example: <application> <resources base=&quot; http://localhost:11109/CustomerDB/resources/ &quot;> <resource path=&quot;/items/&quot;> <method name=&quot;GET&quot;> <request> <param default=&quot;0&quot; type=&quot;xs:int&quot; style=&quot;query&quot;  name=&quot;start&quot;/> <param default=&quot;10&quot; type=&quot;xs:int&quot; style=&quot;query&quot; name=&quot;max&quot;/> </request> <response> <representation mediaType=&quot;application/xml&quot;/> </response> </method>  </resource> </resources> ..... </application>
Example RESTful Catalog
 
JavaFX Stage Scene  Stage  is the  top level container window Scene  is a drawing surface  container that holds the scene graph nodes. content   holds JavaFX graphical elements which define the graphical content of the application.
JavaFX Stage Scene  // Application User Interface var stageContent: Node[]; stageContent = [bgImage,  nextButton, backButton,  titleText,  thumbImageViewGroup,  fullImageView ]; def  stage  =  Stage  { title: &quot;Pet Catalog&quot; width: 201 height: 201 scene : Scene { content : Group { content: bind stageContent } fill: Color.TRANSPARENT } } top level container window container  holds the scene graph  holds graphical  elements
JavaFX Stage Scene  var stageContent: Node[]; stageContent  = [bgImage,  nextButton, backButton,  titleText,  thumbImageViewGroup,  fullImageView ]; def  stage  =  Stage  { title: &quot;Pet Catalog&quot; width: 201 height: 201 scene : Scene { content : Group { content: bind  stageContent } fill: Color.TRANSPARENT } }
RESTful Pet Catalog Web Service  http://petstore/catalog/resources/items/ HTTP  GET Response XML items <item> <imageurl>http://host/catalog/images/anthony.jpg</imageurl> <name>Friendly Cat</name> <price>307.10</price> <productid>feline01</productid> </item>  Server Client  Addressable Resources Web Container
JavaFX  HttpRequest function loadImageMetadata() { var start=page * 9;  var request: HttpRequest = HttpRequest { location:  &quot; http://localhost:8080/catalog/resources/items/ &quot; method: HttpRequest.GET onInput: function(input: java.io.InputStream) {  var parser = PhotoPullParser{}; photos =  parser.parse(input) ;  } onDone: function() { updateImages() ; } } request.enqueue(); } Performs HTTP GET on url  catalog/items
JavaFX  HttpRequest public class PhotoPullParser { public function parse(input: InputStream): Photo[] { var  photos: Photo[]; var photo: Photo; def parser = PullParser {input: input onEvent : function(event: Event) { if ( event.type == PullParser.START_ELEMENT ) { if(event.qname.name == &quot; item &quot; and event.level == 1) { photo = Photo { }; } } else if ( event.type == PullParser.END_ELEMENT ) { if( event.qname.name == &quot; item &quot;  and event.level == 1) { insert photo into photos; } else if( event.qname.name == &quot; imagethumburl &quot;  and event.level == 2) { photo.imagethumburl = event.text; }  ... } } } parser.parse(); return photos; } <item> <imageurl>http://y.jpg</imageurl> <name>Friendly Cat</name> ... </item>
Agenda REST Primer RESTful Design and API Elements Building a Simple Service Status Q & A
Java SE RuntimeDelegate  used to create instances of a desired endpoint class Application supplies configuration information  List of resource classes and providers as subclass of  ApplicationConfig Implementations can support any Java type Jersey supports Grizzly (see below), LW HTTP server and  JAX-WS Provider ApplicationConfig config = ... RuntimeDelegate rd = RuntimeDelegate.getInstance(); Adapter a = rd.createEndpoint(config, Adapter.class); SelectorThread st = GrizzlyServerFactory.create( “ http://127.0.0.1:8084/”, a);
Servlet JAX-RS application packaged in  WAR  like a servlet For JAX-RS aware containers web.xml  can point to  ApplicationConfig  subclass For non-JAX-RS aware containers web.xml  points to implementation-specific  Servlet ; and  an  init-param  identifies the  ApplicationConfig  subclass Resource classes and providers can access  Servlet  request, context, config and response via injection
Java EE 6 Plans JAX-RS is part of Java EE 6 Applications deployed in a Java EE 6 Web container will have access to additional resources: Resources  @Resources  EJB  @EJB ... Stateless session EJBs as resource classes More portable deployment with Servlet 3.0
Agenda REST Primer RESTful Design and API Elements Building a Simple Service Deployment Options Status
Summary REST architecture is gaining popularity Simple, scalable and the infrastructure is already in place JAX-RS (JSR-311) provides a high level declarative programming model http://jersey.dev.java.net Jersey available 1.0 and 1.0.1:  Glassfsh  v2/v3  1.0:  NetBeans  6.5
For More Information Official JSR Page http://jcp.org/en/jsr/detail?id=311 JSR Project http://jsr311.dev.java.net/ Reference Implementation http://jersey.dev.java.net/ Marc's Blog http://weblogs.java.net/blog/mhadley/ Paul's Blog http://blogs.sun.com/sandoz/ Jakub's Blog http://blogs.sun.com/japod/ Carol's Blog http://weblogs.java.net/blog/caroljmcdonald/
Presenter’s Name [email_address] Carol McDonald  Java Architect http://weblogs.java.net/blog/caroljmcdonald/

More Related Content

RESTful Web Services with JAX-RS

  • 1. REST Carol McDonald, Java Architect
  • 2. Agenda REST Primer RESTful Design and API Elements Building a Simple Service Status Q & A
  • 3. REpresentational State Transfer Get http://www.depot.com/parts Response XML data = REpresentational State Transfer The URL identifies the resource HTTP GET method operates on the resource html page is transferred to the browser REpresentational State transfer The page ( application state ) is stored on the client (browser) Click on the link (resource) in page ( hypermedia ) New state transfer occurs
  • 4. REST architecture for the Web Web platforms Addressable Resources Web Container Addressable Resources Web Container
  • 5. REST Tenets Resources ( nouns ) Identified by a URI , For example: http://www.parts-depot.com/parts Methods ( verbs ) to manipulate the nouns Small fixed set: GET, PUT, POST, DELETE Read, Update, Create, Delete Representation of the Resource data and state transferred between client and server XML, JSON ... Use verbs to exchange application state and representation
  • 6. HTTP Example Request GET /music/artists/beatles/recordings HTTP/1.1 Host: media.example.com Accept: application/xml Response HTTP/1.1 200 OK Date: Tue, 08 May 2007 16:41:58 GMT Server: Apache/1.3.6 Content-Type: application/xml; charset=UTF-8 <?xml version=&quot;1.0&quot;?> <recordings xmlns=&quot;…&quot;> <recording>…</recording> … </recordings> Method Resource Representation State transfer
  • 7. REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications http://www.infoq.com/articles/rest-introduction Uniform Interface
  • 8. Give Every Thing an Id http://company.com/customers/123456 Resource Collection name Primary key http://company.com/customers/123456/orders/12 http://example.com/orders/2007/11 http://example.com/products?color=green URI is the id, Every resource has a URI URIs identify : items, collections of items, virtual and physical objects, or computation results.
  • 9. REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications http://www.infoq.com/articles/rest-introduction Uniform Interface
  • 10. Use Standard HTTP Methods: GET = Read GET to retrieve information Should not modify anything Cacheable Example GET /store/customers/123456
  • 11. Use Standard HTTP Methods: POST = Create POST to add new information add the entity , append to the container resource POST /store/customers <customer> <name>carol</name> </customer> Response HTTP/1.1 201 Created Location: http://store/customers/789
  • 12. Use Standard HTTP Methods: PUT = Update PUT to update information Full entity create/replace used when you know the “ id ” Example PUT /store/customers/123456 <customer> <name>jane</name> </customer>
  • 13. Use Standard HTTP Methods: DELETE Remove (logical) an entity Example DELETE /store/customers/123456
  • 14. Use Standard Methods: http://www.infoq.com/articles/rest-introduction Order Customer Mgmt Example
  • 15. Use Standard Methods: /orders GET - list all orders POST - submit a new order /orders/{order-id} GET - get an order representation PUT - update an order DELETE - cancel an order /orders/average-sale GET - calculate average sale /customers GET - list all customers POST - create a new customer /customers/{cust-id} GET - get a customer representation DELETE- remove a customer /customers/{cust-id}/orders GET - get the orders of a customer Order Customer Mgmt Example http://www.infoq.com/articles/rest-introduction
  • 16. Use Standard HTTP Methods HTTP Get, Head Should not modify anything Cache-able With Correct use of Last-Modified and ETag Idempotency: PUT, DELETE, GET, HEAD can be repeated and the results are the same
  • 17. REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications * Inspired by Stefan Tilkov: http://www.innoq.com/blog/st/presentations/2008/2008-03-13-REST-Intro--QCon-London.pdf
  • 18. Link Things Together Representations contain links to other resources Service provides links in response to the Client Enables client to move the application from one state to the next by following a link Representations contain links to other resources: <prop self=&quot; http://example.com/orders/101230 &quot;> <customer ref=&quot; http://example.com/customers/bar &quot;> <product ref=&quot; http://example.com/products/21034 &quot;/> <amount value=&quot;1&quot;/> </order>
  • 19. Link Things Together Representations contain links to other resources Put a service in different states by following links and filling in forms “ Hypermedia as the engine of application state” HTML, XML, JSON, N3 can all be Hypermedia Client is in charge Service offers potential states Service does not impose state transition order
  • 20. REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications * Inspired by Stefan Tilkov: http://www.innoq.com/blog/st/presentations/2008/2008-03-13-REST-Intro--QCon-London.pdf
  • 21. Multiple Representations Offer data in a variety of formats, for different needs XML JSON (X)HTML Support content negotiation Accept header GET /foo Accept: application/json URI-based GET / foo.json
  • 22. content negotiation Multiple Representations Content-type HTTP header Accept HTTP header Request GET /music/artists/beatles/recordings HTTP/1.1 Host: media.example.com Accept : application/xml Response HTTP/1.1 200 OK Date: Tue, 08 May 2007 16:41:58 GMT Server: Apache/1.3.6 Content-Type : application/xml; charset=UTF-8 <?xml version=&quot;1.0&quot;?> <recordings xmlns=&quot;…&quot;> <recording>…</recording> … </recordings> Format Representation
  • 23. REST in Five Steps* Give everything an ID Use standard methods Link things together Multiple representations Stateless communications * Inspired by Stefan Tilkov: http://www.innoq.com/blog/st/presentations/2008/2008-03-13-REST-Intro--QCon-London.pdf
  • 24. Stateless Communications HTTP protocol is stateless Everything required to process a request contained in the request No client session on the server Eliminates many failure conditions application state kept on Client Service responsible for resource state
  • 25. Common Patterns: Container, Item Server in control of URI Container – a collection of items List catalog items: GET /catalog/items Add item to container: POST /catalog/items with item in request URI of item returned in HTTP response header e.g. http://host/ catalog/items/1 Update item: PUT /catalog/items/1 with updated item in request Good example: Atom Publishing Protocol
  • 26. Common Patterns: Map, Key, Value Client in control of URI List key-value pairs : GET /map Put new value to map: PUT /map/{key} with entry in request e.g. PUT /map/dir/contents.xml Read value: GET /map/{key} Update value: PUT /map/{key} with updated value in request Remove value: DELETE /map/{key} Good example: Amazon S3
  • 27. Key Benefits Server side Uniform Interface Cacheable Scalable Easy failover Client side Easy to experiment in browser Broad programming language support Choice of data formats bookmarkable
  • 28. Agenda REST Primer RESTful Design and API Elements with JAX-RS Building a Simple Service Status Q & A
  • 29. JAX-RS: Clear mapping to REST concepts High level, Declarative Uses @ annotation in POJOs Jersey – reference implementation of JSR 311 Download it from http://jersey.dev.java.net Comes with Glassfish, Java EE 6 Tools support in NetBeans Four other open source implementations: Apache CXF JBoss RESTEasy Restlet Triaxrs
  • 30. Give Everything an ID “Thing” == resource class POJO, No required interfaces ID provided by @Path annotation Relative to deployment context Annotate class or “ sub-resource locator” method http://host/ctx/orders/12 http://host/ctx/orders/12/customer @Path( &quot;orders/{id}&quot;) public class OrderResource { @Path(&quot;customer&quot;) CustomerResource getCustomer(...) {...} }
  • 31. Use Standard Methods Annotate resource class methods with standard method @GET , @PUT , @POST , @DELETE , @HEAD annotations on parameters specify mapping from request data Return value mapped to http response @Path(&quot;orders/ {order_id} &quot;) public class OrderResource { @GET Order getOrder( @PathParam (&quot; order_id &quot;) String id) { ... } }
  • 32. Multiple Representations Static and dynamic content negotiation Annotate methods or classes @Produces matches Accepts header @Consumes matches Content-Type header @GET @Consumes(&quot;application/json&quot;) @Produces({&quot;application/xml&quot;,&quot;application/json&quot;}) String getOrder(@PathParam(&quot;order_id&quot;) String id) { ... }
  • 33. Multiple Representations : JAX-RS consuming Annotated method parameters extract client request information @PathParam extracts information from the request URI @QueryParam extracts information from the request URI query parameters http://host/catalog/items/ 123 http://host/catalog/items/ ?start=0
  • 34. Multiple Representations : JAX-RS consuming http://host/catalog/items/?start=0 http://host/catalog/items/123 @Path(&quot;/items/&quot;) @ConsumeMime(“application/xml”) public class ItemsResource { @GET ItemsConverter get( @QueryParam (&quot;start&quot;) int start ) { ... } @Path( &quot;{id}/&quot; ) ItemResource getItemResource( @PathParam (&quot;id&quot;)Long id ){ ... } }
  • 35. Multiple Representations : Supported Types JAX-RS can automatically (un)-marshall between HTTP request/response and Java types “Out-of-the-box” support for the following text/xml, application/xml, application/json – JAXB class */* – byte[] text/* – String application/x-www-form-urlencoded - MultivaluedMap<String, String> response
  • 36. Multiple Representations @Post @ConsumeMime(“application/x-www-form-urlencoded”) @ProduceMime(“application/xml”) public JAXBClass updateEmployee( MultivalueMap<String, String> form) { ... Converted to a map for accessing form's field converted to XML
  • 37. Multiple Representations : producing a response Use Response class to build “created”response @Path(“/items”) class Items { @POST @ProduceMime(“application/xml”) Response create(Ent e) { // persist the new entry, create URI return Response.created ( uriInfo.getAbsolutePath(). resolve(uri+&quot;/&quot;)).build(); } }
  • 38. Uniform interface: HTTP request and response C: POST /items HTTP/1.1 C: Host: host.com C: Content-Type: application/xml C: Content-Length: 35 C: C: <item><name>dog</name></item> S: HTTP/1.1 201 Created S: Location: http://host.com/employees/1234 S: Content-Length: 0
  • 39. Response Codes and Custom Responses JAX-RS returns default response codes GET returns 200 OK PUT returns 201 CREATED See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 200 OK 201 Created 202 Accepted 203 Non-Authoritative Information 204 No Content 205 Reset Content 206 Partial Content 207 Multi-Status 226 IM Used . . .
  • 40. JAX-RS provides Response class @PUT public Response putUser( @PathParam(“id”) int id) { if (!id.equals(userid) ) return Response .status(409).entity( &quot;userids differ&quot;).build(); JAX-RS provides Response class: to specify response codes, to add onto the response can construct more sophisticated return result Can build responses for redirects, errors, ok, setting headers, etc
  • 41. WebApplicationException Example @GET public Employee getEmployee( @PathParam(“id”) int id) { if (!doesEmployeeExist(id)) throw new WebApplicationException( new Throwable(&quot;Resource for &quot; + uriInfo.getAbsolutePath() + &quot; does not exist.&quot;), 404); Response: HTTP Status 404 - Use it when the method has a return type Simple error indicator
  • 42. Link Things Together UriInfo provides information about the request URI and the route to the resource UriBuilder provides facilities to easily build URIs for resources @Context UriInfo info ; OrderResource r = ... UriBuilder b = info.getBaseUriBuilder(); URI u = b.path(OrderResource.class).build(r.id);
  • 43. Statelessness: JAX-RS The default component lifecycle is per-request A new instance created for every request Reduces concurrency issues HTTP session life-cycle is not supported On server side Developer must model state As resource state in the representations
  • 44. Agenda REST Primer RESTful Design and API Elements Building a Simple Service Deployment Options Status
  • 46. Example RESTful Catalog http://weblogs.java.net/blog/caroljmcdonald/archive/2008/08/a_restful_pet_c.html
  • 47. Example RESTful Catalog Service Catalog Database Web container (GlassFish™) + REST API Browser (Firefox) HTTP
  • 48. URIs and Methods: /items GET - list all items POST – add item to catalog /items/{id} GET - get an item representation PUT - update an item DELETE – remove an item Item Catalog Example http://www.infoq.com/articles/rest-introduction
  • 49. Methods Java method name is not significant The @HTTP method is the method @Path(“/items”) class ItemsResource { @GET Items get() { ... } @POST Response create(Item) { ... } } class ItemResource { @GET Item get(...) { ... } @PUT void update(...) { ... } @DELETE void delete(...) { ... } }
  • 50. RESTful Catalog Dojo client, JAX-RS, JAXB, JPA DB Registration Application JAX-RS class Dojo client JAXB class Entity Class ItemsConverter Item ItemsResource
  • 51. Entity Classes Use JPA to map/retrieve data from the database as entities expose entities as RESTful resources entity = resource identified by URL http://host/catalog/items/123 public class Item { int id; String name; String descr; String url; } @Entity @Id Item ID NAME DESC URL
  • 52. Converter Classes JAXB to convert the domain objects (JPA entities ) into XML and/or JSON . DB JAX-RS class Dojo client JAXB class Entity Class ItemsConverter Item ItemsResource
  • 53. ItemConverter JAXB annotated @XmlRootElement(name = &quot;item&quot;) public class ItemConverter { private Item entity; private URI uri; @XmlAttribute public URI getUri() { return uri; } @XmlElement public Long getId() { return (expandLevel > 0) ? entity.getId() : null; } ... }
  • 54. XML <item uri=&quot;http://localhost/Web/resources/items/1/&quot; > <description> black cat is nice</description> <id>1</id> <imagethumburl>/images/anth.jpg</imagethumburl> <name>not Friendly Cat</name> <price>307.10</price> <productid>feline01</productid> </item>
  • 55. JSON { &quot;@uri&quot;:&quot;http://host/catalog/resources/items/1/&quot;, &quot;name&quot;:&quot;Friendly Cat&quot;, &quot;description&quot;:&quot;This black and white colored cat is super friendly.&quot;, &quot;id&quot;:&quot;1&quot;, &quot;imageurl&quot;:&quot; http://localhost:8080/CatalogService/images/anthony.jpg &quot; }
  • 56. ItemsConverter JAXB annotated @XmlRootElement(name = &quot;items&quot;) public class ItemsConverter { private Collection<ItemConverter> items; private URI uri; @XmlAttribute public URI getUri() { return uri; } @XmlElement public Collection<ItemConverter> getItem() { ... return items; } }
  • 57. XML <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <items uri=&quot;http://localhost/Web/resources/items/&quot;> <item uri=&quot;http://localhost/Web/resources/items/1/&quot; > <description> black cat is nice</description> <id>1</id> <imagethumburl>/images/anth.jpg</imagethumburl> <name>not Friendly Cat</name> <price>307.10</price> <productid>feline01</productid> </item> <item . . . </item> </items>
  • 58. JSON { &quot;@uri&quot;:&quot;http://host/catalog/resources/items/&quot;, &quot; item &quot;:[ {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/1/&quot;, &quot;name&quot;:&quot;Friendly Cat&quot;, &quot;description&quot;:&quot;This black and white colored cat is super friendly.&quot;, &quot;id&quot;:&quot;1&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/anthony.jpg&quot;}, {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/2/&quot;, &quot;name&quot;:&quot;Fluffy Cat&quot;, &quot;description&quot;:&quot;A great pet for a hair stylist! &quot;id&quot;:&quot;2&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/bailey.jpg&quot;} ] }
  • 59. Resource Classes Items Resource retrieves updates a collection of Item entities /items – URI for a list of Items Item resource retrieves or updates one Item entity /item/1 – URI for item 1 DB JAX-RS class Dojo client JAXB class Entity Class ItemsConverter Item ItemsResource
  • 60. Get Items @Path(&quot;/items/&quot;) public class ItemsResource { @Context protected UriInfo uriInfo; @GET @Produces (&quot;application/json&quot;) public ItemsConverter get(){ return new ItemsConverter( getEntities(), uriInfo.getAbsolutePath()); } Performs JPA Query, returns list of entities JAXB class responds with JSON responds to the URI http://host/catalog/items/ responds to HTTP GET
  • 61. Get Item @Path(&quot;/items/&quot;) public class ItemsResource { @Path(&quot;{id}/&quot;) public ItemResource getItemResource( @PathParam (&quot;id&quot;) Long id) { return new ItemResource (id, context); } } public class ItemResource { @GET @Produces ( &quot;application/json&quot;) public ItemConverter get() { return new ItemConverter(getEntity(), context.getAbsolutePath(), expandLevel); } JAXB class http://host/catalog/items/123
  • 62. Dojo Client Use dojo.xhrGet to make HTTP method call to catalog service to get JSON items data: {&quot; items &quot;: {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/&quot;, &quot; item &quot;:[ {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/1/&quot;, &quot;name&quot;:&quot;Friendly Cat&quot;, &quot;description&quot;:&quot;This black and white colored cat is super friendly.&quot;, &quot;id&quot;:&quot;1&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/anthony.jpg&quot;}, {&quot;@uri&quot;:&quot;http://host/catalog/resources/items/2/&quot;, &quot;name&quot;:&quot;Fluffy Cat&quot;, &quot;description&quot;:&quot;A great pet for a hair stylist! &quot;id&quot;:&quot;2&quot;, &quot;imageurl&quot;:&quot;http://localhost:8080/CatalogService/images/bailey.jpg&quot;} ] } }
  • 64. Dojo client index.html <button dojoType=&quot;dijit.form.Button&quot; onclick=&quot; next &quot;> Next </button> <div id=&quot;grid&quot; dojoType =&quot; dojox.Grid &quot; model =&quot; model &quot; structure =&quot; layout &quot; autoWidth=&quot;true&quot; > http://weblogs.java.net/blog/caroljmcdonald/archive/2008/08/a_restful_pet_c.html Grid widget
  • 65. Dojo client.js formatImage = function(value) { if (!value) return '&nbsp;'; return &quot;<img src='&quot; + value + &quot;'/>&quot;; }; // Data Grid layout // A grid view is a group of columns var view1 = { cells: [ [ {name: 'Name', field: &quot;name&quot;}, {name: 'Description', field: &quot;description&quot;}, {name: 'Photo',field: &quot;imagethumburl&quot;, formatter: formatImage , }, {name: 'Price',field: &quot;price&quot;} ] ] }; // a grid layout is an array of views. var layout = [ view1 ]; // the model= collection of objects to be displayed in the grid model = new dojox.grid.data.Objects(null,null);
  • 66. RESTful Pet Catalog Web Service http://petstore/catalog/resources/items/ HTTP GET {&quot;url&quot;:&quot;http://store/catalog/item1&quot;, {&quot;url&quot;:&quot;http://store/catalog/item2&quot;} Response JSON slide urls Server Client Addressable Resources Web Container
  • 67. Dojo client.js // make request to the items web service function loadTable (page){ start = page * batchSize; var targetURL = &quot;resources/items/?start=&quot;+ encodeURIComponent(start); dojo.xhrGet ({ url: targetURL , handleAs: &quot;json&quot;, load: handleResponse , error: handleError }); } // Process the response from the items web service function handleResponse ( responseObject , ioArgs){ // set the model object with the returned items list model .setData( responseObject.items.item ); } function next() { page =page + 1; loadTable (page); } Performs HTTP GET on url catalog/items
  • 68. Client & WADL NetBeans IDE can generate JavaScript client stubs from a WADL or projects containing RESTful resources NetBeans IDE exposes popular SaaS services using WADLs and can generate Java code to access them Learn more at https://wadl.dev.java.net/ Example: <application> <resources base=&quot; http://localhost:11109/CustomerDB/resources/ &quot;> <resource path=&quot;/items/&quot;> <method name=&quot;GET&quot;> <request> <param default=&quot;0&quot; type=&quot;xs:int&quot; style=&quot;query&quot; name=&quot;start&quot;/> <param default=&quot;10&quot; type=&quot;xs:int&quot; style=&quot;query&quot; name=&quot;max&quot;/> </request> <response> <representation mediaType=&quot;application/xml&quot;/> </response> </method> </resource> </resources> ..... </application>
  • 70.  
  • 71. JavaFX Stage Scene Stage is the top level container window Scene is a drawing surface container that holds the scene graph nodes. content holds JavaFX graphical elements which define the graphical content of the application.
  • 72. JavaFX Stage Scene // Application User Interface var stageContent: Node[]; stageContent = [bgImage, nextButton, backButton, titleText, thumbImageViewGroup, fullImageView ]; def stage = Stage { title: &quot;Pet Catalog&quot; width: 201 height: 201 scene : Scene { content : Group { content: bind stageContent } fill: Color.TRANSPARENT } } top level container window container holds the scene graph holds graphical elements
  • 73. JavaFX Stage Scene var stageContent: Node[]; stageContent = [bgImage, nextButton, backButton, titleText, thumbImageViewGroup, fullImageView ]; def stage = Stage { title: &quot;Pet Catalog&quot; width: 201 height: 201 scene : Scene { content : Group { content: bind stageContent } fill: Color.TRANSPARENT } }
  • 74. RESTful Pet Catalog Web Service http://petstore/catalog/resources/items/ HTTP GET Response XML items <item> <imageurl>http://host/catalog/images/anthony.jpg</imageurl> <name>Friendly Cat</name> <price>307.10</price> <productid>feline01</productid> </item> Server Client Addressable Resources Web Container
  • 75. JavaFX HttpRequest function loadImageMetadata() { var start=page * 9; var request: HttpRequest = HttpRequest { location: &quot; http://localhost:8080/catalog/resources/items/ &quot; method: HttpRequest.GET onInput: function(input: java.io.InputStream) { var parser = PhotoPullParser{}; photos = parser.parse(input) ; } onDone: function() { updateImages() ; } } request.enqueue(); } Performs HTTP GET on url catalog/items
  • 76. JavaFX HttpRequest public class PhotoPullParser { public function parse(input: InputStream): Photo[] { var photos: Photo[]; var photo: Photo; def parser = PullParser {input: input onEvent : function(event: Event) { if ( event.type == PullParser.START_ELEMENT ) { if(event.qname.name == &quot; item &quot; and event.level == 1) { photo = Photo { }; } } else if ( event.type == PullParser.END_ELEMENT ) { if( event.qname.name == &quot; item &quot; and event.level == 1) { insert photo into photos; } else if( event.qname.name == &quot; imagethumburl &quot; and event.level == 2) { photo.imagethumburl = event.text; } ... } } } parser.parse(); return photos; } <item> <imageurl>http://y.jpg</imageurl> <name>Friendly Cat</name> ... </item>
  • 77. Agenda REST Primer RESTful Design and API Elements Building a Simple Service Status Q & A
  • 78. Java SE RuntimeDelegate used to create instances of a desired endpoint class Application supplies configuration information List of resource classes and providers as subclass of ApplicationConfig Implementations can support any Java type Jersey supports Grizzly (see below), LW HTTP server and JAX-WS Provider ApplicationConfig config = ... RuntimeDelegate rd = RuntimeDelegate.getInstance(); Adapter a = rd.createEndpoint(config, Adapter.class); SelectorThread st = GrizzlyServerFactory.create( “ http://127.0.0.1:8084/”, a);
  • 79. Servlet JAX-RS application packaged in WAR like a servlet For JAX-RS aware containers web.xml can point to ApplicationConfig subclass For non-JAX-RS aware containers web.xml points to implementation-specific Servlet ; and an init-param identifies the ApplicationConfig subclass Resource classes and providers can access Servlet request, context, config and response via injection
  • 80. Java EE 6 Plans JAX-RS is part of Java EE 6 Applications deployed in a Java EE 6 Web container will have access to additional resources: Resources @Resources EJB @EJB ... Stateless session EJBs as resource classes More portable deployment with Servlet 3.0
  • 81. Agenda REST Primer RESTful Design and API Elements Building a Simple Service Deployment Options Status
  • 82. Summary REST architecture is gaining popularity Simple, scalable and the infrastructure is already in place JAX-RS (JSR-311) provides a high level declarative programming model http://jersey.dev.java.net Jersey available 1.0 and 1.0.1: Glassfsh v2/v3 1.0: NetBeans 6.5
  • 83. For More Information Official JSR Page http://jcp.org/en/jsr/detail?id=311 JSR Project http://jsr311.dev.java.net/ Reference Implementation http://jersey.dev.java.net/ Marc's Blog http://weblogs.java.net/blog/mhadley/ Paul's Blog http://blogs.sun.com/sandoz/ Jakub's Blog http://blogs.sun.com/japod/ Carol's Blog http://weblogs.java.net/blog/caroljmcdonald/
  • 84. Presenter’s Name [email_address] Carol McDonald Java Architect http://weblogs.java.net/blog/caroljmcdonald/