jax rs 2.0 - otn bangalore 2013
DESCRIPTION
JAX RS 2.0 - OTN Bangalore 2013TRANSCRIPT
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0A New Standard in RESTful Web Services Development
Jagadish RamuApplication Server GroupOracle
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Agendal REST? What? Why?l JAX-RS 1.1 – The Good, The Bad, The Missingl JAX-RS 2.0 – New Standard for RESTful Web l Services in Java
l Client APIl Asynchronous HTTP processingl Filters & Interceptors
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Why REST
Client-serverStatelessnessUniform InterfaceCacheabilityLayeringCode on Demand
ScalabilitySimplicityEvolvability, ExtensibilityReliabilityPerformance, EfficiencyVisibility
Architectural style constraints which… …translate to system design properties
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Why REST
l HTTP is the Web communication standardl Support for HTTP-based I/O in all modern platforms & languages
l Hassle-free Interoperabilityl Zero Footprint – Mobile device friendly
l Uniform set of HTTP methodsl Easy to understand and consume services
l Data Representation Independencel Services tailored to the client needs
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Agendal REST? What? Why?l JAX-RS 1.1 – The Good, The Bad, The Missingl JAX-RS 2.0 – New Standard for RESTful Web l Services in Java
l Client APIl Asynchronous HTTP processingl Filters & Interceptors
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS - Java API for RESTful Services
Standard annotation-driven APIthat aims to help developers
build RESTful Web services andtheir clients in Java
l POJO-Based Resource l Classes
l Programming model agnostic
l HTTP Centricl Maps HTTP requests to
Java method invocationsl Entity Format Independencel Container Independencel Included in Java EE
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Resources
public class OrderResource {
public List<Order> getOrders() { … }
public Order getOrder(String orderId, String from) { … }
public CustomerResource customer(…) { … } …}
1
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Resources
@Path(“orders”)public class OrderResource { public List<Order> getOrders() { … } @Path(“{id}”) public Order getOrder(String orderId, String from) { … }
@Path(“{id}/customer”) public CustomerResource customer(…) { … }
…}
1
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Resources
@Path(“orders”)public class OrderResource { @GET public List<Order> getOrders() { … } @GET @Path(“{id}”) public Order getOrder(String orderId, String from) { … }
@Path(“{id}/customer”) public CustomerResource customer(…) { … }
…}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Resources
@Produces(“application/xml, text/plain”)@Consumes(“application/xml”) @Path(“orders”)public class OrderResource { @GET public List<Order> getOrders() { … } @GET @Path(“{id}”) public Order getOrder(String orderId, String from) { … }
@Path(“{id}/customer”) public CustomerResource customer(…) { … }
…}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Resources
@Produces(“application/xml, text/plain”)@Consumes(“application/xml”) @Path(“orders”)public class OrderResource { @GET public List<Order> getOrders() { … } @GET @Path(“{id}”) public Order getOrder(@PathParam(“id”) String orderId, @HeaderParam(“From”) @Default(“unknown”) String from) { … }
@Path(“{id}/customer”) public CustomerResource customer(…) { … }
…}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Agendal REST? What? Why?l JAX-RS 1.1 – The Good, The Bad, The Missingl JAX-RS 2.0 – New Standard for RESTful Web l Services in Java
l Client APIl Asynchronous HTTP processingl Filters & Interceptors
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Client APIl Motivation
l HTTP client libraries too low levell Leveraging existing features of JAX-RS 1.x server API
l Entity providers, etc.l Provided by most major JAX-RS 1.x implementations
l Need for a standard
l Fluent APIl Client Builder Client Web Target … Request building
Responsel URI templatingl Configuration inheritance & specialization
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Main Client API Components
l ClientBuilderl Bootstrapping client runtime
l Clientl Main API entry pointl Connection management, configurable
l WebTargetl URI, URI template abstraction (“glorified URI”)l Configurable
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Accessing a service
Client client = ClientBuilder.newClient();
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Accessing a service
Client client = ClientBuilder.newClient();
WebTarget ordersTarget = client.target(“http://example.com/eshop/orders”);
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Accessing a service
Client client = ClientBuilder.newClient();
WebTarget ordersTarget = client.target(“http://example.com/eshop/orders”);
WebTarget orderTarget = ordersTarget.path(“{id}”);
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Accessing a service
Client client = ClientBuilder.newClient();
WebTarget ordersTarget = client.target(“http://example.com/eshop/orders”);
WebTarget orderTarget = ordersTarget.path(“{id}”);
Order order = orderTarget.resolveTemplate(“id”, “1234”) .request(“application/xml”) .get(Order.class);
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Accessing a service
Order newOrder = new Order(…);Response response = ordersTarget.request(“text/plain”) .post(Entity.xml(newOrder));
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Accessing a service
Order newOrder = new Order(…);Response response = ordersTarget.request(“text/plain”) .post(Entity.xml(newOrder));
if (response.getStatus() == 200) { String orderId = response.readEntity(String.class); Link invoiceLink = response.getLink(“invoice”); client.target(invoiceLink).request()…}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Future-based Async Client API
Future<Message> msg = client.target(“http://example.com/messenger”) .request(“application/xml”) .async() .get(Message.class);
while (!msg.isDone()) { // do something else…}
display(msg.get());
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Callback-based Async Client API
client.target(“http://example.com/messenger”) .request(“application/xml”) .async() .get(new InvocationCallback<Message>() { public void completed(Message msg) { display(msg); }
public void failed(Throwable t) { … } });
// do something else…
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Asynchronous JAX-RS Services
l Blocking or long-running operationsl Off-load HTTP I/O container threadl Detach a request processing thread from response
l Represent a suspended client connection in APIl Suspend until a response is availablel Resume when the response is ready
l Leverage Servlet 3.x async support (if available)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Asynchronous Processing: Server-side
@Path(“messenger”)public class MessengerResource { public static Queue<AsyncResponse> messageQueue = …;
@GET @Produces(“application/xml”) public void getMessage(@Suspended AsyncResponse ar) { ar.setTimeoutHandler(new MyTimeoutHandler()); ar.setTimeout(15, SECONDS); messageQueue.put(ar); } …
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Asynchronous Processing: Server-side
…
@POST @Consumes(“application/xml”) public void postMessage(Message msg) { AsyncResponse ar = messageQueue.take(); ar.resume(msg); }}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Asynchronous Processing: Server-side
Suspended
Running Responding Completed
Timing out
TimeoutHandleronTimeout(…)
setTimeout(…)resume(…)/cancel(…)
resume(…)/cancel(…)
CompletionCallbackonComplete(…)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Filters & Interceptors
l Advanced use-casesl For framework, library or advanced developersl Customize JAX-RS request/response processingl Logging, Compression, Security, Etc.
l Introduced for client and server APIsl Replace existing proprietary support
l Provided by most JAX-RS 1.x implementationsl All using slightly different types or semantics
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Filters
l Non-wrapping filter chain l Filters do not invoke next filter in the chain
directlyl managed by the JAX-RS runtime
l Each filter decides to proceed or break the chain (abortWith in RequestFilters)
l Request Processingl ContainerRequestFilterl ClientRequestFilter
l Response Processingl ContainerResponseFilterl ClientResponseFilter
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
A Logging Filter Example
public class RequestLoggingFilter implements ContainerRequestFilter {
@Override public void filter(ContainerRequestContext requestContext) { log(requestContext); // non-wrapping => returns without invoking the next filter }
private void log(ContainerRequestContext requestContext) { … }}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Interceptors
l Invoked ONLY if neededl when/if entity processing occursl Performance boost
l Wrapping interceptor chainl Each interceptor invokes the next one in the
chain via context.proceed()
l MessageBodyReader interceptorl ReaderInterceptor interface
l MessageBodyWriter interceptorl WriterInterceptor interface
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
A GZip Reader Interceptor Example
public class GzipInterceptor implements ReaderInterceptor { @Override public Object aroundReadFrom(ReaderInterceptorContext ctx) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); // wrapping => invokes the next interceptor Object entity = ctx.proceed();
ctx.setInputStream(old); return entity; }}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Binding Filters and Interceptors
l Associating filters and interceptors with resource methodsl Default binding
l Applied to every request / responsel Custom binding
l @NamedBindingl DynamicFeature
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Named Binding
@NameBindingpublic @interface Logged {}
@Logged@BindingPriority(USER)public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { … }
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Named Binding
@Path("/greet/{name}")@Produces("text/plain")public class MyResourceClass {
@Logged @GET public String hello(@PathParam("name") String name) { return "Hello " + name; }}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Dynamic Feature
public interface DynamicFeature { void configure(ResourceInfo ri, FeatureContext context);}
public interface ResourceInfo { Method getResourceMethod(); Class<?> getResourceClass();}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Dynamic Feature
public void SecurityFeature implements DynamicFeature {
public boolean configure(ResourceInfo ri, Configuration config) { String[] roles = getRolesAllowed(ri);
if (roles != null) { config.register(new RolesAllowedFilter(roles)); } } …}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Application
Client Pipeline
Request Filter FilterNetworkTransport
…
…Response FilterFilter
write(…)
WriterInterceptor
… MBW
read(…) - optional
…MBR
WriterInterceptor
ReaderInterceptor
ReaderInterceptor
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Response
Application
Filter Filter
Network
… ResponseFilterFilter
write(…)
…MBW WriterInterceptor
WriterInterceptor
Filter Filter… RequestRequest
read(…) - optional
ReaderInterceptor
… MBRReader
Interceptor
Filter Filter
Resource Matching
@PreMatching
Server Pipeline
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Summary
l Major new featuresl Client API, Filters & Interceptors, Asynchronous support, Common
Configuration, Hypermedia
l Many API improvements and extensionsl Request / Response, UriBuilder, ParamConverter, @BeanParam, MultivaluedHashMap, GenericType, …
l Improved TCK coverage = improved portabilityl ~350 tests in JAX-RS 1.x, ~2300 tests in JAX-RS 2.0
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Jersey 2 – JAX-RS 2.0 RI
l New code-base, repackaged (org.glassfish.jersey)l Unfortunately, incompatible with Jersey 1.x proprietary APIs
l Contribution-friendly (github.com/jersey/jersey)
l Support for all the new JAX-RS 2.0 features & morel Server-sent Events & Chunked datal Dynamic Resource Modelingl Standard Java Dependency Injection API support
l Including the ability to define custom injection bindings
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Q A
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
On the Web
l JAX-RSl Project web site jax-rs-spec.java.netl Users mailing list [email protected] JSR-339 site jcp.org/en/jsr/detail?id=339
l Jerseyl Project web site jersey.java.netl Users mailing list [email protected] Twitter @gf_jersey
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Graphic Section Divider
More JAX-RS 2.0 Features
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Hypermedia in RESTful Applications
REST principlesl Identifiers and Linksl HATEOAS (Hypermedia As The Engine Of App State)
Link types:l Structural Linksl Transitional Links
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Structural vs. Transitional Links
Link: <http://.../orders/1/ship>; rel=ship, <http://.../orders/1/cancel>; rel=cancel ...<order id="1"> <customer>http://.../customers/11</customer> <address>http://.../customers/11/address/1</address> <items> <item> <product>http://.../products/111</product> <quantity>2</quantity> </item> <items> ... </order>
Transitional Links
Structural Links
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS 2.0 Hypermedia Enhancements
Link and LinkBuilder classesl RFC 5988: Web Linking
Support for Link in ResponseBuilder and filtersl Transitional links (headers)
Support for manual structural linksl Via Link.JaxbAdapter & Link.JaxbLink
Create a resource target from a Link in Client API
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Producing Links (Server-side)
Link self = Link.fromResourceMethod(MyResource.class, ”handleGet”) .build();
Link update = Link.fromResourceMethod(MyResource.class, “handlePost”) .rel(”update”) .build();
...
Response res = Response.ok(order) .link("http://.../orders/1/ship", "ship") .links(self, update) .build();
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Consuming Links (Client-side)
// Consumer API (client-side) Order newOrder = new Order(…);Response orderResponse = ordersTarget.request(“text/plain”) .post(Entity.xml(newOrder));
Link shipmentLink = orderResponse.getLink(“ship”);if (shipmentLink != null) { Response shipment = client.target(shipmentLink).post(…); … }
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Server Side Conneg
GET http://.../widgets HTTP/1.1Accept: text/*; q=1.0…
@Path("widgets2")public class WidgetsResource { @GET @Produces("text/plain", "text/html") // ??? public Widgets getWidget() {...}}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Server Side Conneg
GET http://.../widgets HTTP/1.1Accept: text/*; q=1.0…
@Path("widgets2")public class WidgetsResource { @GET @Produces("text/plain,qs=0.5", "text/html,qs=0.75") // !!! public Widgets getWidget() {...}}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Exceptions
WebApplicationExceptionl RedirectionException (3xx)
l getLocation():URIl ClientErrorException (4xx)
l BadRequestException (400), NotAuthorizedException (401), ForbiddenException (403), NotFoundException (404), NotAllowedException (405), NotAcceptableException (406), NotSupportedException (415)
l ServerErrorException (5xx)l InternalServerErrorException (500), ServiceUnavailableException
(503)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
JAX-RS Exceptions
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Working with JAX-RS Exceptions
try { Order order = orderTarget.request(“application/xml”) .get(Order.class);} catch (RedirectionException ex) { // we have to look elsewhere client.target(ex.getLocation()).request()…} catch (ServerErrorException ex) { // it’s not our fault the request failed, let’s retry later…} catch (ClientErrorException ex) { // definitely our fault, let’s see if we can fix the request and retry…}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Server-Sent Events
: an example of a SSE eventid: 1event: text-messagedata: Hello, this is adata: multi-line message.<blank line>
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Server-sent Events in Jersey
OutboundEventEventOutputSseBroadcasterBroadcasterListener
Server side Client side
InboundEventEventInputEventSourceEventListener
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
SSE Server-side
@Path("message/stream")public class MessagesResource { private static SseBroadcaster broadcaster = new SseBroadcaster(); @GET @Produces(SseFeature.SERVER_SENT_EVENTS) public EventOutput getMessageStream() { final EventOutput eventOutput = new EventOutput(); broadcaster.add(eventOutput); return eventOutput; }
…
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
SSE Server-side
…
private static AtomicLong nextMessageId = new AtomicLong(0);
@PUT @Consumes(MediaType.APPLICATION_JSON) public void putMessage(Message message) { OutboundEvent event = new OutboundEvent.Builder() .id(String.valueOf(nextMessageId.getAndIncrement())) .mediaType(MediaType.APPLICATION_JSON_TYPE) .data(Message.class, message) .build();
broadcaster.broadcast(event); }}
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
SSE Client-side – IoC Model
EventSource eventSource = new EventSource(target.path("message/stream")) { @Override public void onEvent(InboundEvent event) { String name = event.getName(); Message message = event.readData(Message.class); display(name, message); } };
…
eventSource.close();
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
SSE Client-side – Pull Model
EventInput events = target.path("message/stream") .request().get(EventInput.class);
while (!stop) { InboundEvent event = events.read(); String name = event.getName(); Message message = event.readData(Message.class); display(name, message); }
events.close();
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.