1 / 54

JAX-RS 2.0: New and Noteworthy in the RESTful Web Services API

JAX-RS 2.0: New and Noteworthy in the RESTful Web Services API. John Clingan Java EE and GlassFish Product Manager john.clingan@oracle.com. JAX-RS Review Client API Common Configuration Asynchronous Processing Filters/Interceptors Hypermedia Support Server-side Content Negotiation.

dava
Download Presentation

JAX-RS 2.0: New and Noteworthy in the RESTful Web Services API

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. JAX-RS 2.0: New and Noteworthy in the RESTful Web Services API John Clingan Java EE and GlassFish Product Manager john.clingan@oracle.com

  2. JAX-RS Review • Client API • Common Configuration • Asynchronous Processing • Filters/Interceptors • Hypermedia Support • Server-side Content Negotiation What’s New in JAX-RS 2.0

  3. JAX-RS – Java API for RESTful Services Standard annotation-driven API that aims to help developers build RESTful Web services and clients in Java • POJO-Based Resource Classes • HTTP Centric Programming Model • Entity Format Independence • Container Independence • Included in Java EE

  4. JAX-RS Example ... @POST @Path("/withdrawal") @Consumes("text/plain") @Produces("application/json") public Money withdraw( @PathParam("card") String card, @QueryParam("pin") String pin, String amount) { return getMoney(card, pin, amount); } }

  5. JAX-RS Annotations

  6. JAX-RS Annotations (Continued)

  7. JAX RS 2.0 Client API

  8. Client API Motivation • HTTP client libraries too low level • Leveraging providers/concepts from JAX-RS 1.x API • Proprietary APIs introduced by major implementations

  9. Client API // Get instance of Client Client client = ClientBuilder.newClient(); // Get account balance String bal = client.target("http://.../atm/{cardId}/balance") .resolveTemplate("cardId", "111122223333") .queryParam("pin", "9876") .request("text/plain").get(String.class);

  10. Client API // Withdraw some money Moneymoney =client.target("http://.../atm/{cardId}/withdrawal") .resolveTemplate("cardId", "111122223333") .queryParam("pin", "9876") .request("application/json") .post(text("50.0"), Money.class);

  11. Client API Invocationinvocation1 = client.target("http://.../atm/{cardId}/balance")… .request(“text/plain”).buildGet(); Invocationinvocation2 = client.target("http://.../atm/{cardId}/withdraw")… .request("application/json") .buildPost(text("50.0"));

  12. Client API Collection<Invocation> invocations =Arrays.asList(inv1, inv2); Collection<Response> responses = Collections.transform( invocations, new F<Invocation, Response>() { public Responseapply(Invocationinvocation) { return invocation.invoke(); } });

  13. Client API // Create client and register MyProvider1 Client client = ClientBuilder.newClient(); client.register(MyProvider1.class); // Create atm target; inherits MyProvider1 WebTargetatm = client.target("http://.../atm"); // Register MyProvider2 atm.register(MyProvider2.class); // Create balance target; inherits MyProvider1, MyProvider2 WebTarget balance = atm.path(”{cardId}/balance"); // Register MyProvider3 balance.register(MyProvider3.class);

  14. JAX RS 2.0Common Configuration

  15. Common Configuration - Motivation Client-side client .register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .property(“jsonp.callback.name”, “callback”) .property(“jsonp.callback.queryParam”, “true”) ...

  16. Common Configuration - Motivation Server-side public class MyApp extends javax.ws.rs.core.Application { public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<…>(); ... classes.add(JsonMessageBodyReader.class); classes.add(JsonMessageBodyWriter.class); classes.add(JsonpInterceptor.class); ... return classes; } }

  17. Common Configuration - Solution Client-side client .register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .property(“jsonp.callback.name”, “callback”) .property(“jsonp.callback.queryParam”, “true”) ... JsonFeaturejf= new JsonFeature().enableCallbackQueryParam(); client.register(jf);

  18. Common Configuration - Solution Server-side public Set<Class<?>> getClasses() { ... classes.add(JsonMessageBodyReader.class); classes.add(JsonMessageBodyWriter.class); classes.add(JsonpInterceptor.class); ... } public Set<Class<?>> getClasses() { ... classes.add(JsonFeature.class); ... }

  19. Common Configuration public interface Configurable { Configuration getConfiguration(); Configurable property(String name, Object value); Configurable register(...); } public interface Configuration { Set<Class> getClasses(); Map<Class,Integer> getContracts(Class componentClass); Set<Object> getInstances(); Map<String,Object> getProperties(); Object getProperty(String name); Collection<String> getPropertyNames(); boolean isEnabled(Feature feature); boolean isRegistered(Object component); ... }

  20. Common Configuration public interface Feature { boolean configure(FeatureContext context); }

  21. A Feature Example public void JsonFeature implements Feature { public boolean configure(FeatureContext context) { context.register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .property(CALLBACK_NAME, calbackName) .property(USE_QUERY_PARAM, useQueryParam); return true; } }

  22. Dynamic Feature Server-side only public interface DynamicFeature { void configure(ResourceInfo ri, FeatureContext context); } public interface ResourceInfo { Method getResourceMethod(); Class<?> getResourceClass(); }

  23. JAX RS 2.0Asynchronous Processing

  24. Asynchronous Processing • Server API • Off-load I/O container threads • Efficient asynchronous event processing • Leverage Servlet 3.x async support (if available) • Client API • Asynchronous request invocation API

  25. Asynchronous Processing @Stateless @Path("/async/longRunning") public class MyResource { @GET @Asynchronous public void longRunningOp(@SuspendedAsyncResponse ar) { ar.setTimeoutHandler(new MyTimoutHandler()); ar.setTimeout(15, SECONDS); final String result = executeLongRunningOperation(); ar.resume(result); } }

  26. Asynchronous Processing: Server Side public interface AsyncResponse { public void resume(Object/Throwable response); public void cancel(); public void cancel(int/Date retryAfter); public boolean isSuspended(); public boolean isCancelled(); public boolean isDone(); public void setTimeout(long time, TimeUnit unit); public void setTimeoutHandler(TimeoutHandler handler); public Collection<Class<?>> register(Class<?> callback); public Map<Class<?>,Collection<Class<?>>> register(Class<?> callback, Class<?>... callbacks); public Collection<Class<?>> register(Object callback); public Map<Class<?>,Collection<Class<?>>> register(Object callback, Object... callbacks); }

  27. Asynchronous Processing: Server Side @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Suspended { } public interface TimeoutHandler { void handleTimeout(AsyncResponse asyncResponse); }

  28. Asynchronous Processing: Server Side public interface CompletionCallback { public void onComplete(Throwable throwable); } public interface ConnectionCallback { public void onDisconnect(AsyncResponse disconnected); }

  29. Asynchronous Processing: Client Side WebTarget target = client.target("http://.../balance”)… // Start async call and register callback Future<?> handle = target.request().async().get( new InvocationCallback<String>() { void complete(String balance) { … } void failed(InvocationException e) { … } }); // After waiting for too long… if (!handle.isDone()) handle.cancel(true);

  30. JAX RS 2.0Filters/Interceptors

  31. Filters & Interceptors Motivation • Customize JAX-RS request/response processing • Use Cases: Logging, Compression, Security, etc. • Introduced for client and server APIs • Replace existing proprietary support

  32. Filters & Interceptors Filter each incoming/outgoing message • Request  Request • ContainerRequestFilter, ClientRequestFilter • Response  Response • ContainerResponseFilter, ClientResponseFilter • Server-side specialties • @PreMatching, DynamicFeature • Non-wrapping filter chain • Filters do not invoke next filter in the chain directly • Managed by the JAX-RS runtime • Each filter decides to proceed or break the chain

  33. Filters & Interceptors A Logging Filter Exampe public class RequestLoggingFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { log(requestContext); // non-wrapping => returns without invoking the next filter } ... }

  34. Filters & Interceptors Intercept entity providers • Invoked ONLY when/if entity processing occurs • Performance boost • Wrapping interceptors chain • Each interceptor invokes the next one in the chain via context.proceed() • MessageBodyReader interceptor • ReaderInterceptorinterface • MessageBodyWriter interceptor • WriterInterceptorinterface

  35. Filters & Interceptors A Gzip Reader Interceptor Example public class GzipInterceptor implements ReaderInterceptor { @Override 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; } }

  36. Filters & Interceptors write(…) … Transport Writer Interceptor Writer Interceptor MBW Response Network • Application … Request Filter Filter … Filter Filter read(…) - optional … MBR Reader Interceptor Reader Interceptor

  37. Filters & Interceptors read(…) - optional … Reader Interceptor Reader Interceptor MBR @PreMatching Network Resource Matching … Application Request Filter Filter Filter Request Filter … Filter Filter Response Response Filter Filter write(…) … MBW Writer Interceptor Writer Interceptor

  38. Bindings & Priorities • Binding • Associating filters and interceptors with resource methods • Server-side concept • Priority • Declaring relative position in the execution chain • @Priority(int priority) • Shared concept by filters and interceptors

  39. Bindings @NameBinding @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged {} @Provider @Logged @Priority(USER) public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { … }

  40. Bindings @Path("/greet/{name}") @Produces("text/plain") public class MyResourceClass { @Logged @GET public String hello(@PathParam("name") String name) { return "Hello " + name; } }

  41. A DynamicFeatureExample Server-side only public void SecurityFeature implements DynamicFeature { public boolean configure(ResourceInfo ri, FeatureContext context) { String[] roles = getRolesAllowed(ri); if (roles != null) { context.register(new RolesAllowedFilter(roles)); } } ... }

  42. JAX RS 2.0Hypermedia Support

  43. Hypermedia Support • REST Principles • Identifiers and Links • HATEOAS (Hypermedia As The Engine Of App State) • Link types: • Structural Links • Transitional Links

  44. Hypermedia Support 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> Structural Links

  45. Hypermedia • Link and LinkBuilder classes • RFC 5988: Web Linking • Support for Link in ResponseBuilder and filters • Transitional links (headers) • Support for manual structural links • Via Link.JaxbAdapter & Link.JaxbLink • Create a resource target from a Link in Client API

  46. Hypermedia // Producer API (server-side) Link self= Link.fromMethod(MyResource.class, ”handleGet”) .build(); Link update= Link.fromMethod(MyResource.class, “handlePost”) .rel(”update”) .build(); ... Response res = Response.ok(order) .link("http://.../orders/1/ship", "ship") .links(self, update) .build();

  47. Hypermedia Response order = client.target(…).request("application/xml").get(); // Consumer API (client-side) Link shipmentLink = order.getLink(“ship”); if (shipmentLink != null) { Response shipment = client.target(shipmentLink).post(null); … }

  48. JAX RS 2.0Server-side Content Negotiation

  49. Server-side Content Negotiation GET http://.../widgets2 Accept: text/*; q=1 … Path("widgets2") public class WidgetsResource2 { @GET @Produces("text/plain", "text/html") public Widgets getWidget() {...} }

More Related