Mais conteúdo relacionado
Semelhante a JAX RS 2.0 - OTN Bangalore 2013 (20)
Mais de Jagadish Prasath (6)
JAX RS 2.0 - OTN Bangalore 2013
- 1. JAX-RS 2.0
A New Standard in RESTful Web Services Development
Jagadish Ramu
Application Server Group
Oracle
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 2. 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.
- 3. Agenda
l REST? What? Why?
l JAX-RS 1.1 – The Good, The Bad, The Missing
l JAX-RS 2.0 – New Standard for RESTful Web
l Services in Java
l Client API
l Asynchronous HTTP processing
l Filters & Interceptors
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 4. Why REST
Architectural style constraints which… …translate to system design properties
Client-server
Statelessness
Uniform Interface
Cacheability
Layering
Code on Demand
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Scalability
Simplicity
Evolvability, Extensibility
Reliability
Performance, Efficiency
Visibility
- 5. Why REST
l HTTP is the Web communication standard
l Support for HTTP-based I/O in all modern platforms & languages
l Hassle-free Interoperability
l Zero Footprint – Mobile device friendly
l Uniform set of HTTP methods
l Easy to understand and consume services
l Data Representation Independence
l Services tailored to the client needs
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 6. Agenda
l REST? What? Why?
l JAX-RS 1.1 – The Good, The Bad, The Missing
l JAX-RS 2.0 – New Standard for RESTful Web
l Services in Java
l Client API
l Asynchronous HTTP processing
l Filters & Interceptors
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 7. JAX-RS - Java API for RESTful Services
Standard annotation-driven API
that aims to help developers
build RESTful Web services and
their clients in Java
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
l POJO-Based Resource
l Classes
l Programming model
agnostic
l HTTP Centric
l Maps HTTP requests to
Java method invocations
l Entity Format Independence
l Container Independence
l Included in Java EE
- 8. JAX-RS Resources
public class OrderResource {
public List<Order> getOrders() { … }
public Order getOrder(String orderId,
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
String from) { … }
public CustomerResource customer(…) { … }
…
}
- 9. JAX-RS Resources
@Path(“orders”)
public class OrderResource {
public List<Order> getOrders() { … }
@Path(“{id}”)
public Order getOrder(String orderId,
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
String from) { … }
@Path(“{id}/customer”)
public CustomerResource customer(…) { … }
…
}
- 10. JAX-RS Resources
@Path(“orders”)
public class OrderResource {
@GET
public List<Order> getOrders() { … }
@GET
@Path(“{id}”)
public Order getOrder(String orderId,
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
String from) { … }
@Path(“{id}/customer”)
public CustomerResource customer(…) { … }
…
}
- 11. 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,
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
String from) { … }
@Path(“{id}/customer”)
public CustomerResource customer(…) { … }
…
}
- 12. 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,
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
@HeaderParam(“From”) @Default(“unknown”) String from) { …
}
@Path(“{id}/customer”)
public CustomerResource customer(…) { … }
…
}
- 13. Agenda
l REST? What? Why?
l JAX-RS 1.1 – The Good, The Bad, The Missing
l JAX-RS 2.0 – New Standard for RESTful Web
l Services in Java
l Client API
l Asynchronous HTTP processing
l Filters & Interceptors
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 14. JAX-RS 2.0 Client API
l Motivation
l HTTP client libraries too low level
l 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 API
l Client Builder Client Web Target … Request building
Response
l URI templating
l Configuration inheritance & specialization
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 15. Main Client API Components
l ClientBuilder
l Bootstrapping client runtime
l Client
l Main API entry point
l Connection management, configurable
l WebTarget
l URI, URI template abstraction (“glorified URI”)
l Configurable
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 16. Accessing a service
Client client = ClientBuilder.newClient();
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 17. 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.
- 18. 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.
- 19. 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”)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.request(“application/xml”)
.get(Order.class);
- 20. Accessing a service
Order newOrder = new Order(…);
Response response = ordersTarget.request(“text/plain”)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.post(Entity.xml(newOrder));
- 21. Accessing a service
Order newOrder = new Order(…);
Response response = ordersTarget.request(“text/plain”)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.post(Entity.xml(newOrder));
if (response.getStatus() == 200) {
String orderId = response.readEntity(String.class);
Link invoiceLink = response.getLink(“invoice”);
client.target(invoiceLink).request()…
}
- 22. Future-based Async Client API
Future<Message> msg
= client.target(“http://example.com/messenger”)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.request(“application/xml”)
.async()
.get(Message.class);
while (!msg.isDone()) {
// do something else…
}
display(msg.get());
- 23. 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.
- 24. Asynchronous JAX-RS Services
l Blocking or long-running operations
l Off-load HTTP I/O container thread
l Detach a request processing thread from response
l Represent a suspended client connection in API
l Suspend until a response is available
l 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.
- 25. 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.
- 26. 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.
- 27. Asynchronous Processing: Server-side
Suspended
resume(…)/cancel(…)
Running Responding Completed
Timing out
TimeoutHandler
onTimeout(…)
setTimeout(…)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
resume(…)/cancel(…)
CompletionCallback
onComplete(…)
- 28. JAX-RS 2.0 Filters & Interceptors
l Advanced use-cases
l For framework, library or advanced developers
l Customize JAX-RS request/response processing
l Logging, Compression, Security, Etc.
l Introduced for client and server APIs
l Replace existing proprietary support
l Provided by most JAX-RS 1.x implementations
l All using slightly different types or semantics
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 29. JAX-RS 2.0 Filters
l Non-wrapping filter chain
l Filters do not invoke next filter in the chain
directly
l managed by the JAX-RS runtime
l Each filter decides to proceed or break
the chain (abortWith in RequestFilters)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
l Request Processing
l ContainerRequestFilter
l ClientRequestFilter
l Response Processing
l ContainerResponseFilter
l ClientResponseFilter
- 30. 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.
- 31. JAX-RS 2.0 Interceptors
l Invoked ONLY if needed
l when/if entity processing occurs
l Performance boost
l Wrapping interceptor chain
l Each interceptor invokes the next one in the
chain via context.proceed()
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
l MessageBodyReader interceptor
l ReaderInterceptor interface
l MessageBodyWriter interceptor
l WriterInterceptor interface
- 32. 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.
- 33. Binding Filters and Interceptors
l Associating filters and interceptors with resource methods
l Default binding
l Applied to every request / response
l Custom binding
l @NamedBinding
l DynamicFeature
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 34. Named Binding
@NameBinding
public @interface Logged {}
@Logged
@BindingPriority(USER)
public class LoggingFilter
implements ContainerRequestFilter, ContainerResponseFilter { … }
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 35. 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.
- 36. 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.
- 37. 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.
- 38. Client Pipeline
Application
write(…)
Writer
Interceptor … MBW
Request Filter Filter
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Transport Network
…
Response Filter … Filter
read(…) - optional
MBR …
Writer
Interceptor
Reader
Interceptor
Reader
Interceptor
- 39. Server Pipeline
Request Filter … Filter Request
Response
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Application
Filter Filter
Network
Filter … Filter Response
write(…)
MBW Writer …
Interceptor
Writer
Interceptor
read(…) - optional
Reader
Interceptor … Reader MBR
Interceptor
Filter Filter
Resource
Matching
@PreMatching
- 40. JAX-RS 2.0 Summary
l Major new features
l Client API, Filters & Interceptors, Asynchronous support, Common
Configuration, Hypermedia
l Many API improvements and extensions
l Request / Response, UriBuilder, ParamConverter,
@BeanParam, MultivaluedHashMap, GenericType, …
l Improved TCK coverage = improved portability
l ~350 tests in JAX-RS 1.x, ~2300 tests in JAX-RS 2.0
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 41. 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 & more
l Server-sent Events & Chunked data
l Dynamic Resource Modeling
l 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.
- 42. Q A
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 43. On the Web
l JAX-RS
l Project web site jax-rs-spec.java.net
l Users mailing list users@jax-rs-spec.java.net
l JSR-339 site jcp.org/en/jsr/detail?id=339
l Jersey
l Project web site jersey.java.net
l Users mailing list users@jersey.java.net
l Twitter @gf_jersey
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 45. Graphic Section Divider
More JAX-RS 2.0 Features
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 46. Hypermedia in RESTful Applications
REST principles
l Identifiers and Links
l HATEOAS (Hypermedia As The Engine Of App State)
Link types:
l Structural Links
l Transitional Links
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 47. 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>
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
Transitional
Links
Structural
Links
- 48. JAX-RS 2.0 Hypermedia Enhancements
Link and LinkBuilder classes
l RFC 5988: Web Linking
Support for Link in ResponseBuilder and filters
l Transitional links (headers)
Support for manual structural links
l 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.
- 49. 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.
- 50. Consuming Links (Client-side)
// Consumer API (client-side)
Order newOrder = new Order(…);
Response orderResponse = ordersTarget.request(“text/plain”)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.post(Entity.xml(newOrder));
Link shipmentLink = orderResponse.getLink(“ship”);
if (shipmentLink != null) {
Response shipment = client.target(shipmentLink).post(…);
…
}
- 51. Server Side Conneg
GET http://.../widgets HTTP/1.1
Accept: 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.
- 52. Server Side Conneg
GET http://.../widgets HTTP/1.1
Accept: 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.
- 53. JAX-RS Exceptions
WebApplicationException
l RedirectionException (3xx)
l getLocation():URI
l 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.
- 55. Working with JAX-RS Exceptions
try {
Order order = orderTarget.request(“application/xml”)
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.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…
}
- 56. Server-Sent Events
: an example of a SSE event
id: 1
event: text-message
data: Hello, this is a
data: multi-line message.
<blank line>
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
- 57. Server-sent Events in Jersey
Server side Client side
OutboundEvent
EventOutput
SseBroadcaster
BroadcasterListener
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
InboundEvent
EventInput
EventSource
EventListener
- 58. 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.
- 59. 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.
- 60. 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.
- 61. SSE Client-side – Pull Model
EventInput events = target.path("message/stream")
Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
.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();