JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
-
Upload
arun-gupta -
Category
Documents
-
view
4.766 -
download
2
description
Transcript of JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 1
JAX-RS 2.0: New and Noteworthy in RESTful Web Services API Arun Gupta Java EE & GlassFish Guy blogs.oracle.com/arungupta, @arungupta
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 2
JAX-RS - Java API for RESTful Services
§ POJO-Based Resource Classes § HTTP Centric Programming Model § Entity Format Independence § Container Independence § Included in Java EE
Standard annotation-driven API that aims to help developers
build RESTful Web services and clients in Java
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 3
Example: JAX-RS API @Path("/atm/{cardId}")public class AtmService { @GET @Path("/balance") @Produces("text/plain") public String balance(@PathParam("cardId") String card, @QueryParam("pin") String pin) { return Double.toString(getBalance(card, pin)); } …
Built-in Serialization
Resources
URI Parameter Injection
HTTP Method Binding
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 4
Example: JAX-RS API (contd.) … @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); }}
Custom Serialization
Param Binding
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 5
Example: JAX-RS API (contd.)
Param Binding
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 6
Example: JAX-RS API (contd.)
Param Binding
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 7
JSR-339 a.k.a. JAX-RS 2.0
§ Expert Group formed in February, 2011 – Lead by Oracle
§ Marek Potociar, Santiago Pericas-Geertsen – 13 Group members
§ Jan Algermissen, Florent Benoit (OW2), Sergey Beryozkin (Talend/CXF), Adam Bien, Bill Burke (RedHat), Clinton L Combs, Bill De Hora, Markus Karg, Sastry Mallady (eBay), Wendy Raschke (IBM), Julian Reschke, Guilherme Silveira, Dionysios Synodinos
§ Public Review Draft published on Sep 28, 2012 – See JSR-339 JCP site jcp.org/en/jsr/detail?id=339
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 8
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 9
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 10
Client API
§ HTTP client libraries too low level § Leveraging providers and concepts from the JAX-RS 1.x API
– E.g., MBRs and MBWs § Proprietary APIs introduced by major JAX-RS 1.x implementations
– Need for a standard
Motivation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 11
Client API
// Get instance of Client Client client = ClientFactory.newClient(); // Get account balance String bal = client.target("http://.../atm/{cardId}/balance") .resolveTemplate("cardId", "111122223333") .queryParam("pin", "9876") .request("text/plain").get(String.class);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 12
Client API
// Withdraw some money Money mon = client.target("http://.../atm/{cardId}/withdrawal") .resolveTemplate("cardId", "111122223333") .queryParam("pin", "9876") .request("application/json") .post(text("50.0"), Money.class);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 13
Client API
Invocation inv1 = client.target("http://.../atm/{cardId}/balance")… .request(“text/plain”).buildGet(); Invocation inv2 = client.target("http://.../atm/{cardId}/withdraw")… .request("application/json") .buildPost(text("50.0"));
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 14
Client API
Collection<Invocation> invocations = Arrays.asList(inv1, inv2); Collection<Response> responses = Collections.transform( invocations, new F<Invocation, Response>() { public Response apply(Invocation inv) { return inv.invoke(); } });
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 15
Client API
// Create client and register MyProvider1 Client client = ClientFactory.newClient(); client.configuration().register(MyProvider1.class); // Create atm target; inherits MyProvider1 WebTarget atm = client.target("http://.../atm"); // Register MyProvider2 atm.configuration().register(MyProvider2.class); // Create balance target; inherits MyProvider1, MyProvider2 WebTarget balance = atm.path(”{cardId}/balance"); // Register MyProvider3 balance.configuration().register(MyProvider3.class);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 16
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 17
Common configuration - motivation
client.configuration() .register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .setProperty(“jsonp.callback.name”, “callback”) .setProperty(“jsonp.callback.queryParam”, “true”) ...
Client-side
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 18
Common configuration - motivation
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; } }
Server-side
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 19
Common configuration - solution
client.configuration() .register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .setProperty(“jsonp.callback.name”, “callback”) .setProperty(“jsonp.callback.queryParam”, “true”) ... JsonFeature jf = new JsonFeature().enableCallbackQueryParam(); Client.configuration().register(jf);
Client-side
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 20
Common configuration - solution
public Set<Class<?>> getClasses() { … classes.add(JsonMessageBodyReader.class); classes.add(JsonMessageBodyWriter.class); classes.add(JsonpInterceptor.class); … } public Set<Class<?>> getClasses() { … classes.add(JsonFeature.class); … }
Server-side
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 21
Common configuration
public interface Configurable { Map<String, Object> getProperties(); Object getProperty(String name); Configurable setProperties(Map<String, ?> properties); Configurable setProperty(String name, Object value); Collection<Feature> getFeatures(); Set<Class<?>> getProviderClasses(); Set<Object> getProviderInstances(); Configurable register(...); ... }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 22
Common configuration
public interface Feature { boolean configure(Configurable configurable); }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 23
A Feature example
public void JsonFeature implements Feature { public boolean configure(Configurable config) { config.register(JsonMessageBodyReader.class) .register(JsonMessageBodyWriter.class) .register(JsonpInterceptor.class) .setProperty(CALLBACK_NAME, calbackName) .setProperty(USE_QUERY_PARAM, useQueryParam); return true; } }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 24
Dynamic Feature
public interface DynamicFeature { void configure(ResourceInfo ri, Configurable configurable); } public interface ResourceInfo { Method getResourceMethod(); Class<?> getResourceClass(); }
Server-side only
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 25
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 26
Async Processing
§ Server API support – Off-load I/O container threads
§ Long-running operations – Efficient asynchronous event processing
§ Suspend while waiting for an event § Resume when event arrives
– Leverage Servlet 3.x async support (if available)
§ Client API support – Asynchronous request invocation API
§ Future<RESPONSE>, InvocationCallback<RESPONSE>
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 27
Async Processing: Server-side
@Path("/async/longRunning") public class MyResource { @GET public void longRunningOp(@Suspended AsyncResponse ar) { ar.setTimeoutHandler(new MyTimoutHandler()); ar.setTimeout(15, SECONDS); Executors.newSingleThreadExecutor().submit(new Runnable() { public void run() { … ar.resume(result); } }); } }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 28
Async 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 boolean register(Class<?> callback); public boolean[] register(Class<?> callback, Class<?>... callbacks); public boolean register(Object callback); public boolean[] register(Object callback, Object... callbacks); }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 29
Async Processing: Server-side
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Suspended { } public interface TimeoutHandler { void handleTimeout(AsyncResponse asyncResponse); }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 30
Async Processing: Server-side
public interface ResumeCallback { public void onResume(AsyncResponse resuming, Response response); public void onResume(AsyncResponse resuming, Throwable error); } public interface CompletionCallback { public void onComplete(); public void onError(Throwable throwable); } public interface ConnectionCallback { public void onDisconnect(AsyncResponse disconnected); }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 31
Async 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);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 32
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 33
Filters & Interceptors
§ Customize JAX-RS request/response processing – Use Cases: Logging, Compression, Security, Etc.
§ Introduced for client and server APIs § Replace existing proprietary support
– Provided by most JAX-RS 1.x implementations § All using slightly different types or semantics
Motivation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 34
Filters & Interceptors
§ 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
Filter each incoming/outgoing message
§ Request è Request – ContainerRequestFilter, ClientRequestFilter
§ Response è Response – ContainerResponseFilter, ClientResponseFilter
§ Server-side specialties – @PreMatching, DynamicFeature
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 35
Filters & Interceptors
public class RequestLoggingFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { log(requestContext); // non-wrapping => returns without invoking the next filter } ... }
A Logging Filter Example
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 36
Filters & Interceptors
§ Invoked ONLY when/if entity processing occurs
– Performance boost
§ Wrapping interceptor chain – Each interceptor invokes the next
one in the chain via context.proceed()
Intercept entity providers
§ MessageBodyReader interceptor – ReaderInterceptor interface
§ MessageBodyWriter interceptor – WriterInterceptor interface
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 37
Filters & Interceptors
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; } }
A GZip Reader Interceptor Example
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 38
Application
Filters & Interceptors
Request Filter Filter Network Transport
… … Response Filter Filter
write(…)
Writer Interceptor
… MBW
read(…) - optional
… MBR
Writer Interceptor
Reader Interceptor
Reader Interceptor
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 39
Response
Application
Filters & Interceptors
Filter Filter Network
… Response Filter Filter
write(…)
… MBW Writer Interceptor
Writer Interceptor
Filter Filter … Request Request
read(…) - optional
Reader Interceptor
… MBR Reader Interceptor
Filter Filter
Resource Matching
@PreMatching
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 40
Bindings & Priorities § Binding
– Associating filters and interceptors with resource methods – Server-side concept
§ Priority – Declaring relative position in the execution chain – @BindingPriority(int priority)
§ Shared concept by filters and interceptors
Scoped Binding Global Binding
Static @NameBinding (@Qualifier?) Default
@PreMatching
Dynamic DynamicFeature N/A
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 41
Bindings
@NameBinding // or @Qualifier ? @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged {} @Provider @Logged @BindingPriority(USER) public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { … }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 42
Bindings
@Path("/greet/{name}") @Produces("text/plain") public class MyResourceClass { @Logged @GET public String hello(@PathParam("name") String name) { return "Hello " + name; } }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 43
A DynamicFeature example
public void SecurityFeature implements DynamicFeature { public boolean configure(ResourceInfo ri, Configurable config) { String[] roles = getRolesAllowed(ri); if (roles != null) { config.register(new RolesAllowedFilter(roles)); } } … }
Server-side only
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 44
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 45
Hypermedia
§ REST principles – Identifiers and Links – HATEOAS (Hypermedia As The Engine Of App State)
§ Link types:
– Structural Links – Transitional Links
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 46
Hypermedia
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 © 2012, Oracle and/or its affiliates. All rights reserved. 47
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
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 48
Hypermedia
// Producer API (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 © 2012, Oracle and/or its affiliates. All rights reserved. 49
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); … }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 50
JAX-RS 2.0
§ Client API § Common configuration § Asynchronous processing § Filters § Interceptors § Hypermedia support § Server-side content negotiation
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 51
Server Side Conneg
GET http://.../widgets2 Accept: text/*; q=1 … Path("widgets2") public class WidgetsResource2 { @GET @Produces("text/plain", "text/html") public Widgets getWidget() {...} }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 52
Server Side Conneg
GET http://.../widgets2 Accept: text/*; q=1 … Path("widgets2") public class WidgetsResource2 { @GET @Produces("text/plain; qs=0.5", "text/html; qs=0.75") public Widgets getWidget() {...} }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 53
JAX-RS 2.0 Summary
§ Major new features – Client API, Filters & Interceptors, Asynchronous Resources, Hypermedia
§ Many minor API improvements and extensions – Request / Response, URI builder, String Converters, @BeanParam, MultivaluedHashMap, GenericType, …
§ Improved TCK coverage = improved portability – ~350 tests in JAX-RS 1.x, ~1700 tests in JAX-RS 2.0
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 54
<a href=“…” >JAX-RS 2.0</a>
§ Project web site jax-rs-spec.java.net § Users mailing list [email protected] § JSR-339 site jcp.org/en/jsr/detail?id=339
– Latest specification text draft § java.net/projects/jax-rs-spec/sources/git/content/spec/spec.pdf
– Latest API snapshot § jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/index.html
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 55
<a href=“…” >Jersey 2.0</a>
§ Project web site jersey.java.net § Users mailing list [email protected]
– Latest users guide § http://jersey.java.net/nonav/documentation/snapshot/index.html
– Latest API documentation § http://jersey.java.net/nonav/apidocs/snapshot/jersey/index.html
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 56
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 57
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 58
JAX-RS 2.0
§ DI (JSR-330) Integration § Bean Validation § Improved Java EE Security Support § Presentation Layer § High-level Client API
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 59
Dependency Injection Integration
§ Support Java Dependency Injection API (JSR-330) – Support @Inject and @Qualifier ? – @Qualifier as a replacement for @NamedBinding ? – Provider vs. ContextResolver ? – Support DI (JSR-330) or CDI (JSR-299)?
§ Issues – Interference with CDI providers – EG does not see enough added value for DI
§ DI-style injection support deferred
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 60
Dependency Injection Integration
§ Java EE Deployments – Tight CDI integration makes sense (unification of Java EE component
model) § Java SE Deployments
– DI provides all the required features – CDI is too heavy-weight
§ Many redundant features – method interceptors, decorators, stereotypes …
§ Additional limitations put on managed components
Support DI (JSR-330) or CDI (JSR-299)?
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 61
Bean Validation
§ Dropped from JAX-RS 2.0 Public Review – Difficulty aligning schedules
§ Still supported via CDI 1.1 – JAX-RS resource class must be CDI bean – BV 1.1 now supports method validation
§ May revisit current plan post Java EE 7
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 62
More Topics…
§ Improved Java EE security support
– @RolesAllowed, … – SecurityContext.authenticate(…)
§ Pluggable Views – Completes the MVC pattern
§ High-level client API – Hard to design it to be RESTful – Jersey 2 provides an
experimental support – Don’t want to end-up with an
RPC-style API