The document discusses the JAX-RS 2.0 client API, including that it has 4 core classes, providers must be registered, uses a fluent API with immutable instances, and request bodies are represented by the Entity class.
23. Launching Requests
Response res =
customerWt
.request(application/customer)
.get();
int status = res.getStatus();
Locale loc = res.getLanguage();
Link editLink = res.getLink(edit);
Customer c = res.readEntity(
Customer.class);
24. Sending Data
WebTarget customersWT = client
.target(http://crm.example.com/customers);
Customer customer = new Customer(Pebbles Flintstone);
Response res = customersWT.request(application/customer).post(
Entity.entity(customer, application/customer));
175. And what about the entity?
public interface ContainerResponseContext {
OutputStream getEntityStream();
Object getEntity();
void setEntityStream(OutputStream outputStream);
void setEntity();
}
Here
184. gzip-Filter - 1st Try
public void filter(ContainerResponseContext res) ... {
OutputStream old = res.getEntityStream();
GzipOutputStream gzipFilterStream = new GzipOutputStream(old);
res.setEntityStream(gzipFilterStream);
}
185. gzip-Filter - 1st Try
public void filter(ContainerResponseContext res) ... {
OutputStream old = res.getEntityStream();
GzipOutputStream gzipFilterStream = new GzipOutputStream(old);
res.setEntityStream(gzipFilterStream);
// and at some point...
gzipOutputStream.finish(); ???
}
186. gzip-Filter - 1st Try
public void filter(ContainerResponseContext res) ... {
OutputStream old = res.getEntityStream();
GzipOutputStream gzipFilterStream = new GzipOutputStream(old);
res.setEntityStream(gzipFilterStream);
// and at some point...
gzipOutputStream.finish(); ???
}
Filters
335. getSize()
public interface MessageBodyWriterT {
long getSize(T t, Class? type, Type genericType,
Annotation[] annotations, MediaType mediaType);
}
As of JAX-RS 2.0, the method has been
deprecated and the value returned by the
method is ignored by a JAX-RS runtime. All
MessageBodyWriter implementations are
advised to return -1 from the method.
Responsibility to compute the actual Content-
Length header value has been delegated to
555. Binding Priorities
public interface javax.ws.rs.BindingPriority extends
java.lang.annotation.Annotation{
public static final int AUTHENTICATION;
public static final int AUTHORIZATION;
public static final int HEADER_DECORATOR;
public static final int ENTITY_CODER;
public static final int USER;
public abstract int value();
}
609. globally?
@Provider @Path(entries/{id})
@Logged public class EntryResource {
public class LogFilter ...
@GET @Logged
public Entry getEntry() { ... }
}
708. pools!
ADMIN
Long-
HTTP
Runnin
Worker
g
Thread
Thread
s
709. @GET @Path(large-thing)
public void getLargeThing(@Suspended AsyncResponse ar) {
Executors.newSingleThreadExecutor().submit(new Runnable() {
public void run() {
// long running: building the large thing
ar.resume(LARGE THING);
}
They
725. Async in Client API
calendarWt.request(text/calendar).async().get(
new InvocationCallbackCalendarData() {
You
726. bet!
public void completed(CalendarData cal) {
calendarWidget.display(cal);
}
public void failed(ClientException ex) {
calendarWidget.showMessage(
Event could not be downloaded,
Reason: + ex.getMessage());
}
});
Did
785. Not Just in Resources
@Provider
public class MyFilter implements ContainerResponseFilter {
private Link serviceLink =
Link.fromResource(Service.class,service).build();
public void filter(ContainerRequestContext req,
ContainerResponseContext res) throws IOException {
res.getHeaders().add(Link,serviceLink.toString());
}
}
823. @Path(entries)
public class EntriesResource { Subresource
@Path({id})
public EntryResource findEntry(@PathParam(id) String id) {
return new EntryResource(id);
}
}
public class EntryResource {
public EntryResource(String id) { ... }
@GET
public Entry getEntry() {
...
}
}
824. @Path(entries)
public class EntriesResource { Subresource
@Path({id})
public EntryResource findEntry(@PathParam(id) String id) {
return new EntryResource(id);
}
}
public class EntryResource {
No D
public EntryResource(String id) { ... }
@GET
I her
public Entry getEntry() {
}
...
e!
}
825. @Path(entries)
public class EntriesResource {
@Context ResourceContext rc; Subresource
@Path({id})
public EntryResource findEntry(@PathParam(id) String id) {
return rc.initResource(new EntryResource(id));
}
}
826. @Path(entries)
public class EntriesResource {
@Context ResourceContext rc; Subresource
@Path({id})
public EntryResource findEntry(@PathParam(id) String id) {
return rc.initResource(new EntryResource(id));
}
}
public class EntryResource {
@Context HttpHeaders headers;
public EntryResource(String id) { ... }
@GET
public Entry getEntry() {
return new Entry();
}
}
827. @Provider
class TestFilter implements ContainerRequestFilter {
@Context
ResourceContext rc;
void filter(ContainerRequestContext requestContext) ... {
Widget w = rc.getResource(Widget.class);
Gadget g = rc.initResource(new Gadget(...));
}
}
And
836. @Provider
class MyInterceptor implements WriterInterceptor {
@Context ResourceContext rc;
public void aroundWriteTo(WriterInterceptorContext ctx) ... {
OutputStream os = ctx.getOutputStream();
MyFilterOutputStream fos = rc.initResource(
new MyFilterOutputStream(os) );
ctx.setOutputStream(fos);
ctx.proceed();
}
}
837. public class MyFilterOutputStream extends FilterOutputStream {
@PathParam(id) String id;
@HeaderParam(Referer) String referer
public MyFilterOutputStream( OutputStream os) {
super(os);
}
public write(byte[] b) {
// use request information while filtering stream
}
}
838. @Provider @PreMatching
class TestFilter implements ContainerRequestFilter { W
@ on
’t
@Context
Pr wo
ResourceContext rc;
e M rk
void filter(ContainerRequestContext requestContext) ... { at wi
ch th
Widget w = rc.getResource(Widget.class); in
Gadget g = rc.initResource(new Gadget(...));
g
}
}
I am Jan Algermissen\nComplete REST Head\nWorking as consultant based in Hamburg, Germany. By now Fulltime REST\nSo I am a happy person :-)\nStanding here because I happen to be part of the JAX-RS expert group.\n\nFirst, I owe you an apology because the abstract of the talk...\nI am around all week. If you feel like discussing real world REST systems drop me a line and I'll make it up to you.\n
Before hitting a key:\nLet's learn about you:\n- who knows JAX-RS, who doesn't? To those, I apologize, I'll not cover the JAX-RS 1 features\n- who is active user?\n- and anybody considers herself a power user?\n- finally: any \n- Talking about jax-rs 2.0 new features\n- Who is user? Who would consider himself\n- I will briefly show the main aspects\n- found implications quite unintuitive at times\n- and not blogged about much, so far. not much out there to learn\n- thus, my goal here is to provide you with enaough detail so you get away\n with an understanding of how to approach the new API. How its olves problems\n you are facing and what new ideas you might have based on th ecapabilities.\nAFTER BUILT IN:\nGoing to take you on a wild tour through the new features.\nAlso help you develop a base for exploring what's possible. Help you develop new ideas.\n\n
Before hitting a key:\nLet's learn about you:\n- who knows JAX-RS, who doesn't? To those, I apologize, I'll not cover the JAX-RS 1 features\n- who is active user?\n- and anybody considers herself a power user?\n- finally: any \n- Talking about jax-rs 2.0 new features\n- Who is user? Who would consider himself\n- I will briefly show the main aspects\n- found implications quite unintuitive at times\n- and not blogged about much, so far. not much out there to learn\n- thus, my goal here is to provide you with enaough detail so you get away\n with an understanding of how to approach the new API. How its olves problems\n you are facing and what new ideas you might have based on th ecapabilities.\nAFTER BUILT IN:\nGoing to take you on a wild tour through the new features.\nAlso help you develop a base for exploring what's possible. Help you develop new ideas.\n\n
Before hitting a key:\nLet's learn about you:\n- who knows JAX-RS, who doesn't? To those, I apologize, I'll not cover the JAX-RS 1 features\n- who is active user?\n- and anybody considers herself a power user?\n- finally: any \n- Talking about jax-rs 2.0 new features\n- Who is user? Who would consider himself\n- I will briefly show the main aspects\n- found implications quite unintuitive at times\n- and not blogged about much, so far. not much out there to learn\n- thus, my goal here is to provide you with enaough detail so you get away\n with an understanding of how to approach the new API. How its olves problems\n you are facing and what new ideas you might have based on th ecapabilities.\nAFTER BUILT IN:\nGoing to take you on a wild tour through the new features.\nAlso help you develop a base for exploring what's possible. Help you develop new ideas.\n\n
Before hitting a key:\nLet's learn about you:\n- who knows JAX-RS, who doesn't? To those, I apologize, I'll not cover the JAX-RS 1 features\n- who is active user?\n- and anybody considers herself a power user?\n- finally: any \n- Talking about jax-rs 2.0 new features\n- Who is user? Who would consider himself\n- I will briefly show the main aspects\n- found implications quite unintuitive at times\n- and not blogged about much, so far. not much out there to learn\n- thus, my goal here is to provide you with enaough detail so you get away\n with an understanding of how to approach the new API. How its olves problems\n you are facing and what new ideas you might have based on th ecapabilities.\nAFTER BUILT IN:\nGoing to take you on a wild tour through the new features.\nAlso help you develop a base for exploring what's possible. Help you develop new ideas.\n\n
Before hitting a key:\nLet's learn about you:\n- who knows JAX-RS, who doesn't? To those, I apologize, I'll not cover the JAX-RS 1 features\n- who is active user?\n- and anybody considers herself a power user?\n- finally: any \n- Talking about jax-rs 2.0 new features\n- Who is user? Who would consider himself\n- I will briefly show the main aspects\n- found implications quite unintuitive at times\n- and not blogged about much, so far. not much out there to learn\n- thus, my goal here is to provide you with enaough detail so you get away\n with an understanding of how to approach the new API. How its olves problems\n you are facing and what new ideas you might have based on th ecapabilities.\nAFTER BUILT IN:\nGoing to take you on a wild tour through the new features.\nAlso help you develop a base for exploring what's possible. Help you develop new ideas.\n\n
Before hitting a key:\nLet's learn about you:\n- who knows JAX-RS, who doesn't? To those, I apologize, I'll not cover the JAX-RS 1 features\n- who is active user?\n- and anybody considers herself a power user?\n- finally: any \n- Talking about jax-rs 2.0 new features\n- Who is user? Who would consider himself\n- I will briefly show the main aspects\n- found implications quite unintuitive at times\n- and not blogged about much, so far. not much out there to learn\n- thus, my goal here is to provide you with enaough detail so you get away\n with an understanding of how to approach the new API. How its olves problems\n you are facing and what new ideas you might have based on th ecapabilities.\nAFTER BUILT IN:\nGoing to take you on a wild tour through the new features.\nAlso help you develop a base for exploring what's possible. Help you develop new ideas.\n\n
Client API has been there in the frameworks in proprietary form.\nPrimary benefit really is the consolidation into a standardized API.\n\nMost of you are likely familiar with the concepts, but some of it yields interesting aspects.\n
Generic client\nNeed to register providers\nSupport for Apache client will be interesting with 2.0\n
Various ways to create WebTargets\nNew instance every time\n\n-> Sometimes you need many of a kind; WTs support URI temaplates.\n
\n
\n
Entity class used to determine request media type\n
General and built in entity functions\n
Suppose you are doing the same over and over again...\n
Better to reuse the thing to invoce\n\n=> but sometimes you need variations of a request\n
In the fluid API of clients side request building is InvocationBuilder\n\nWe can use that to 'parameterize' invocations.\n
Also applies when we have different request bodies in turns\n
Creates a WebTraget using built in client\n\nrelative URI references are resolved relative to the JAX-RS runtime application path.\n\nNot sure how useful such self-WebTargets are.\n\nClient should be configurable in runtime impl. dependent way\n
Creates a WebTraget using built in client\n\nrelative URI references are resolved relative to the JAX-RS runtime application path.\n\nNot sure how useful such self-WebTargets are.\n\nClient should be configurable in runtime impl. dependent way\n
\n\n
\n\n
\n\n
\n\n
\n\n
\n\n
\n\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
PreMatching filters can change the input to the matching algorithm\n
Request filters can abort processing of the filter chain and return directly.\n
\n
Now let us write a compressing filter\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Architectural Mismatch!\n
Architectural Mismatch!\n
Architectural Mismatch!\n
Architectural Mismatch!\n
Architectural Mismatch!\n
Architectural Mismatch!\n
Architectural Mismatch!\n
Architectural Mismatch!\n
=> That's actually not even the whole story because if you change the stream you are always in danger of producing incorrect HTTP messages.\n
Unfortunately that is only half of the problem.\n\nWhen changing the stream you are working around HTTP content negotiation.\n\nConsider Accept-Language and translating the stream in an interceptor.\n\nMuch like compressing it - actually, the runtime is in charge of conneg.\n\nConsider this:\n
\n
\n
\n
Client request headers not accessable ... until ResourceContext\n\nHaving said that, the advice is:\n
Having said that, here is one more example.\n\n
Here is an example that does not have these issues because it holds the stream and can then change the headers.\n
\n
\n
\n
\n
\n
\n
\n
Why do we have both, what is the difference, really? This sums it up.\n\n
Why do we have both, what is the difference, really? This sums it up.\n\n
Why do we have both, what is the difference, really? This sums it up.\n\n
Why do we have both, what is the difference, really? This sums it up.\n\n
Why do we have both, what is the difference, really? This sums it up.\n\n
Why do we have both, what is the difference, really? This sums it up.\n\n
Why do we have both, what is the difference, really? This sums it up.\n\n
\n
\n
\n
\n
\n
\n
So, how do filters and interceptors get associated with the chains?\nTwo differnt sides: server side (managed by JAX-RS runtime) and client side (explicit registering)\nconstrained to, named binding, feature, dynamic feature, global\nAchtung bei binding (bind instance, bind class (that is: bind the singleton) and maybe limit bind to a certain contract interface (iow not all implemented interfaces of the registered provider\n\n
Use @Provider to have runtime detect them. bound to all stuff per default\nYou can not use @Provider and register with ApplicationConfig instead but that is uncommen IMO\n
\n
\n
\n
\n
\n
\n
configure() is called in turn for every resource and resource method\n\nYour implementation must decide what to register for each of them.\n\nTaking into account whatever other parameters there are (e.g. debug=true)\n
You can provide class *or* instance.\n\nProvide class means: use or create a managed instance\n\nProvide instance creates a dedicated, not(!) managed instance. DI won't work in there\n
Use @Provider to have runtime detect them. bound to all stuff per default\nYou can not use @Provider and register with ApplicationConfig instead but that is uncommen IMO\n
register() changes target object\nconfiguration is inherited\ndeep copy is made\n
register() changes target object\nconfiguration is inherited\ndeep copy is made\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
=> Of course, now there immediately arise the question: "What about the client side?"\n
Beware that you might loose events - this is not guaranteed delivery\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
fromMethod() will not survive renamings\n
fromMethod() will not survive renamings\n
\n
\n
\n
\n
\n\n
\n\n
\n\n
\n\n
1.1 - Subresource locator has no DI\n
1.1 - Subresource locator has no DI\n
\n
\n
\n
Same works for interceptors, of course\n
\n
One final remark: won't work in PreMatching filters.\n
\n\n
\n\n
\n\n
Advice: interceptors just monitoring etc.\n
Advice: interceptors just monitoring etc.\n
Advice: interceptors just monitoring etc.\n
Advice: interceptors just monitoring etc.\n
Advice: interceptors just monitoring etc.\n
Advice: interceptors just monitoring etc.\n
Advice: interceptors just monitoring etc.\n
Currently API is still changing a bit.\nI'll put together a blog this week containing links and how to try the latest in an EE context with GF.\n\n\n
Mention slides uploaded and links/more info in blog\nOrder QA by aspects.\n