The Newest JAX-RS Features      Jan Algermissen NORD Software Consulting@algermissen • http://jalg.net
What’s in 2.0 For Me?
What’s in 2.0 For Me?          Client
 API
What’s in 2.0 For Me?          Client
 API          Filters
What’s in 2.0 For Me?          Client
 API          Filters          Interceptors
What’s in 2.0 For Me?          Client
 API          Filters          Interceptors          Async
What’s in 2.0 For Me?          Client
 API          Filters          Interceptors          Async          Hypermedia
What’s in 2.0 For Me?          Client
 API          Filters          Interceptors          Async          Hypermedia          ResourceContext
Client API  Now
 I
 am
 standardized!
Client client = ClientFactory.newClient();client.register(CustomerMessageBodyWriter.class);client.register(CustomerMessage...
Aiming at WebTargets     WebTarget crmWt = client       .target(http://example.com/crm);     WebTarget customersWT = crm.p...
WebTarget carWT = client.target(http://example.com/car/{plateNr});carWT.resolveTemplate(plateNr,HH-TZ-101);carWT.resolveTe...
Launching RequestsResponse res = customerWt .request(application/customer) .get();int status = res.getStatus();Locale loc ...
Sending DataWebTarget customersWT = client  .target(http://crm.example.com/customers);Customer customer = new Customer(Peb...
import static javax.ws.rs.client.Entity.*;...post( Entity.entity(customer, application/customer) );...post(xml(customer));...
Why build many...WebTarget latestCustomersWT = client  .target(http://example.com/customers/latest);while( keepPolling ) {...
...if you can use just one?WebTarget latestCustomersWT = client .target(http://example.com/customers/latest);Invocation po...
Need variations on a theme?InvocationBuilder pollBuilder = latestCustomersWT   .request(application/atom+xml).acceptLangua...
Creating a Bunch of CustomersInvocationBuilder createBuilder = customersWT                         .request(application/cu...
 works
                      for
 sending
 data,
 too.
@Uri(http://crm/news)           @Uri
 creates
 WebTargets.       @Uri(http://example.com/crm)       WebTarget crmServiceWt;       @Uri(entries/latest);       WebTarget ...
@Uri(orders/{name})                                                Inside
 a
      resource
 class
 you
 may
 use
              templates.            @Path(users/{name})            pulic class UserResource {                  @Uri(orders...
Client API
Client API-
 4
 core
 classes
Client API-
 4
 core
 classes-
 providers
 must
 be
 .registered()
Client API-
 4
 core
 classes-
 providers
 must
 be
 .registered()-
 Fluent
 API,
 immutable
 instances
Client API-
 4
 core
 classes-
 providers
 must
 be
 .registered()-
 Fluent
 API,
 immutable
 instances-
 .request(
 [accept]
 )
Client API-
 4
 core
 classes-
 providers
 must
 be
 .registered()-
 Fluent
 API,
 immutable
 instances-
 .request(
 [accept]
 )-
 request
 body
 -
 Entity
 class
Client API-
 4
 core
 classes-
 providers
 must
 be
 .registered()-
 Fluent
 API,
 immutable
 instances-
 .request(
 [accept]
 )-
 request
 body
 -
 Entity
 class-
 separation
 of
 concerns
 (Invocation)
Client API-
 4
 core
 classes-
 providers
 must
 be
 .registered()-
 Fluent
 API,
 immutable
 instances-
 .request(
 [accept]
 )-
 request
 body
 -
 Entity
 class-
 separation
 of
 concerns
 (Invocation)-@Uri
@Provider                                Filterspublic class MyFilter implements                  ContainerRequestFilter, ...
er  rv eSe i d   -s
er  rv eSe i d   -s
er  rv eSe i d   -s
er  rv eSe i d   -s
er  rv eSe i d   -s
er  rv eSe i d   -s
er  rv eSe i d   -s
er  rv eSe i d   -s
-    nt lie eC d si
-    nt lie eC d si
-    nt lie eC d si
-    nt lie eC d si
-    nt lie eC d si
-    nt lie eC d si
-    nt lie eC d si
Logging Filterpublic void filter(ClientRequestContext req) ... {    log.info( +req.getMethod()+ +req.getUri().toASCIIString...
Header-Decorating Filter@Providerpublic class CacheControlDecoratorFilter implements                        ContainerRespo...
@Provider @PreMatchingpublic class RewriteFilter implements                   ContainerRequestFilter { public void filter(C...
Abort Filter Chainif( !isValid(authToken) )   req.abortWith(Response.status(401).build());
Authentication Filter@Overridepublic void filter(ContainerRequestContext req)                        throws IOException { U...
And what about the entity?public interface ContainerResponseContext {    OutputStream getEntityStream();    Object getEnti...
 you
 see
 how
 to
 access
                 the
 response
Upcoming SlideShare
Loading in …5
×

JAX-RS 2.0 New Features

5,358 views
5,195 views

Published on

Introduction to the latest developments of the JAX-RS 2.0 specification.

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,358
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
128
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide
  • \n
  • 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
  • JAX-RS 2.0 New Features

    1. 1. The Newest JAX-RS Features Jan Algermissen NORD Software Consulting@algermissen • http://jalg.net
    2. 2. What’s in 2.0 For Me?
    3. 3. What’s in 2.0 For Me? Client
    4. 4.  API
    5. 5. What’s in 2.0 For Me? Client
    6. 6.  API Filters
    7. 7. What’s in 2.0 For Me? Client
    8. 8.  API Filters Interceptors
    9. 9. What’s in 2.0 For Me? Client
    10. 10.  API Filters Interceptors Async
    11. 11. What’s in 2.0 For Me? Client
    12. 12.  API Filters Interceptors Async Hypermedia
    13. 13. What’s in 2.0 For Me? Client
    14. 14.  API Filters Interceptors Async Hypermedia ResourceContext
    15. 15. Client API Now
    16. 16.  I
    17. 17.  am
    18. 18.  standardized!
    19. 19. Client client = ClientFactory.newClient();client.register(CustomerMessageBodyWriter.class);client.register(CustomerMessageBodyReader.class);client.register(SomeFeature.class);client.setProperty(CLIENT_CACHE_SIZE,100);
    20. 20. Aiming at WebTargets WebTarget crmWt = client .target(http://example.com/crm); WebTarget customersWT = crm.path(customers); WebTarget frenchCustWT = customersWt .matrixParam(country,france); WebTarget custSearchWT = frenchCustWT .queryParam(q,Yves);
    21. 21. WebTarget carWT = client.target(http://example.com/car/{plateNr});carWT.resolveTemplate(plateNr,HH-TZ-101);carWT.resolveTemplate(plateNr,M-KL-1982);carWT.resolveTemplate(plateNr,F-EK-7622);carWT.resolveTemplate(plateNr,HB-RE-223);carWT.resolveTemplate(plateNr,B-AM-8719);
    22. 22. Launching RequestsResponse 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);
    23. 23. Sending DataWebTarget 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));
    24. 24. import static javax.ws.rs.client.Entity.*;...post( Entity.entity(customer, application/customer) );...post(xml(customer));...post(json(customer));...post(text(customer));...post(html(customer));...post( form( new Form(firstname,Pebbles).param(surname , Flintstone) )); Request entity encoding optio ns
    25. 25. Why build many...WebTarget latestCustomersWT = client .target(http://example.com/customers/latest);while( keepPolling ) { Response res = latestCustomersWT.request(application/atom+xml) .acceptLanguage(de) .header(...).header(...).get(); ...}
    26. 26. ...if you can use just one?WebTarget latestCustomersWT = client .target(http://example.com/customers/latest);Invocation poll = latestCustomersWT .request(application/atom+xml) .acceptLanguage(de) .header(...).header(...).buildGet();while( keepPolling ) { Response res = poll.invoke(); ...}
    27. 27. Need variations on a theme?InvocationBuilder pollBuilder = latestCustomersWT .request(application/atom+xml).acceptLanguage(de) .header(...).header(...);while( keepPolling ) { Response res = pollBuilder.header(If-None-Match,etag).get(); if( notModified ) continue; ...}
    28. 28. Creating a Bunch of CustomersInvocationBuilder createBuilder = customersWT .request(application/customer) .acceptLanguage(de) .header(...).header(...);for(Customer c : newCustomers ) { Response res = createBuilder.post( Entity.entity(c, application/customer));} InvocationBuilder
    29. 29.  works
    30. 30.   for
    31. 31.  sending
    32. 32.  data,
    33. 33.  too.
    34. 34. @Uri(http://crm/news) @Uri
    35. 35.  creates
    36. 36.  WebTargets. @Uri(http://example.com/crm) WebTarget crmServiceWt; @Uri(entries/latest); WebTarget latestEntriesWt;
    37. 37. @Uri(orders/{name}) Inside
    38. 38.  a
    39. 39.   resource
    40. 40.  class
    41. 41.  you
    42. 42.  may
    43. 43.  use
    44. 44.   templates. @Path(users/{name}) pulic class UserResource { @Uri(orders/{name}) WebTarget userOrderWt; @Uri(http://mail.org/box/{name}); WebTarget userMailboxWt; }
    45. 45. Client API
    46. 46. Client API-
    47. 47.  4
    48. 48.  core
    49. 49.  classes
    50. 50. Client API-
    51. 51.  4
    52. 52.  core
    53. 53.  classes-
    54. 54.  providers
    55. 55.  must
    56. 56.  be
    57. 57.  .registered()
    58. 58. Client API-
    59. 59.  4
    60. 60.  core
    61. 61.  classes-
    62. 62.  providers
    63. 63.  must
    64. 64.  be
    65. 65.  .registered()-
    66. 66.  Fluent
    67. 67.  API,
    68. 68.  immutable
    69. 69.  instances
    70. 70. Client API-
    71. 71.  4
    72. 72.  core
    73. 73.  classes-
    74. 74.  providers
    75. 75.  must
    76. 76.  be
    77. 77.  .registered()-
    78. 78.  Fluent
    79. 79.  API,
    80. 80.  immutable
    81. 81.  instances-
    82. 82.  .request(
    83. 83.  [accept]
    84. 84.  )
    85. 85. Client API-
    86. 86.  4
    87. 87.  core
    88. 88.  classes-
    89. 89.  providers
    90. 90.  must
    91. 91.  be
    92. 92.  .registered()-
    93. 93.  Fluent
    94. 94.  API,
    95. 95.  immutable
    96. 96.  instances-
    97. 97.  .request(
    98. 98.  [accept]
    99. 99.  )-
    100. 100.  request
    101. 101.  body
    102. 102.  -
    103. 103.  Entity
    104. 104.  class
    105. 105. Client API-
    106. 106.  4
    107. 107.  core
    108. 108.  classes-
    109. 109.  providers
    110. 110.  must
    111. 111.  be
    112. 112.  .registered()-
    113. 113.  Fluent
    114. 114.  API,
    115. 115.  immutable
    116. 116.  instances-
    117. 117.  .request(
    118. 118.  [accept]
    119. 119.  )-
    120. 120.  request
    121. 121.  body
    122. 122.  -
    123. 123.  Entity
    124. 124.  class-
    125. 125.  separation
    126. 126.  of
    127. 127.  concerns
    128. 128.  (Invocation)
    129. 129. Client API-
    130. 130.  4
    131. 131.  core
    132. 132.  classes-
    133. 133.  providers
    134. 134.  must
    135. 135.  be
    136. 136.  .registered()-
    137. 137.  Fluent
    138. 138.  API,
    139. 139.  immutable
    140. 140.  instances-
    141. 141.  .request(
    142. 142.  [accept]
    143. 143.  )-
    144. 144.  request
    145. 145.  body
    146. 146.  -
    147. 147.  Entity
    148. 148.  class-
    149. 149.  separation
    150. 150.  of
    151. 151.  concerns
    152. 152.  (Invocation)-@Uri
    153. 153. @Provider Filterspublic class MyFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext req) { // mutable request } public void filter(ContainerRequestContext req, ContainerResponseContext res) { // mutable response, immutable request }}
    154. 154. er rv eSe i d -s
    155. 155. er rv eSe i d -s
    156. 156. er rv eSe i d -s
    157. 157. er rv eSe i d -s
    158. 158. er rv eSe i d -s
    159. 159. er rv eSe i d -s
    160. 160. er rv eSe i d -s
    161. 161. er rv eSe i d -s
    162. 162. - nt lie eC d si
    163. 163. - nt lie eC d si
    164. 164. - nt lie eC d si
    165. 165. - nt lie eC d si
    166. 166. - nt lie eC d si
    167. 167. - nt lie eC d si
    168. 168. - nt lie eC d si
    169. 169. Logging Filterpublic void filter(ClientRequestContext req) ... { log.info( +req.getMethod()+ +req.getUri().toASCIIString()); MultivaluedMapString, String headers = req.getStringHeaders(); for (String key : headers.keySet()) { ListString values = headers.get(key); log.info( +key+: +headers.get(key)); }}
    170. 170. Header-Decorating Filter@Providerpublic class CacheControlDecoratorFilter implements ContainerResponseFilter { public void filter(ContainerRequestContext req, ContainerResponseContext res) throws IOException { res.getHeaders().putSingle( Cache-Control,max-age=60,must-revalidate); }}
    171. 171. @Provider @PreMatchingpublic class RewriteFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext req)...{ UriInfo uriInfo = req.getUriInfo(); URI rewrittenUri = uriInfo.getRequestUri(); .... req.setRequestUri(rewrittenUri); }}
    172. 172. Abort Filter Chainif( !isValid(authToken) ) req.abortWith(Response.status(401).build());
    173. 173. Authentication Filter@Overridepublic void filter(ContainerRequestContext req) throws IOException { URI loginUri = UriBuilder .fromMethod(LoginResource.class, getLoginForm) .build(); String authToken = req.getCookies().get(sid).getValue(); if( !isValid(authToken) ) { req.abortWith(Response.temporaryRedirect(loginUri).build()); }}
    174. 174. And what about the entity?public interface ContainerResponseContext { OutputStream getEntityStream(); Object getEntity(); void setEntityStream(OutputStream outputStream); void setEntity();} Here
    175. 175.  you
    176. 176.  see
    177. 177.  how
    178. 178.  to
    179. 179.  access
    180. 180.   the
    181. 181.  response
    182. 182.  entity.
    183. 183. gzip-Filter - 1st Trypublic void filter(ContainerResponseContext res) ... { OutputStream old = res.getEntityStream(); GzipOutputStream gzipFilterStream = new GzipOutputStream(old); res.setEntityStream(gzipFilterStream);}
    184. 184. gzip-Filter - 1st Trypublic void filter(ContainerResponseContext res) ... { OutputStream old = res.getEntityStream(); GzipOutputStream gzipFilterStream = new GzipOutputStream(old); res.setEntityStream(gzipFilterStream); // and at some point... gzipOutputStream.finish(); ???}
    185. 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(); ??? } Filters
    186. 186.  done Need
    187. 187.  to
    188. 188.  call
    189. 189.  finish
    190. 190.  after
    191. 191.  MBW
    192. 192. Interceptors
    193. 193. @Providerclass MinimalInterceptor implements ReaderInterceptor, WriterInterceptor { public Object aroundReadFrom(ReaderInterceptorContext readCtx) { Object entity = readCtx.proceed(); return entity; } public void aroundWriteTo(WriterInterceptorContext writeCtx) { writeCtx.proceed(); }}
    194. 194. er rv eSe i d -s
    195. 195. er rv eSe i d -s
    196. 196. - nt lie eC d si
    197. 197. - nt lie eC d si
    198. 198. Another tryat entitycompression
    199. 199. void aroundWriteTo(WriterInterceptorContext ctx) { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOs = new GZIPOutputStream(old); ctx.setOutputStream(gzipOs); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); }}
    200. 200. Houston
    201. 201.  ...
    202. 202.  Runtime... Houston
    203. 203.  ...
    204. 204.  Runtime...-
    205. 205.  asks
    206. 206.  MBW
    207. 207.  for
    208. 208.  getSize() Houston
    209. 209.  ...
    210. 210.  Runtime...-
    211. 211.  asks
    212. 212.  MBW
    213. 213.  for
    214. 214.  getSize() Houston
    215. 215.  ...-
    216. 216.  sets
    217. 217.  Content-Length
    218. 218.  if
    219. 219.  not
    220. 220.  0
    221. 221.  Runtime...-
    222. 222.  asks
    223. 223.  MBW
    224. 224.  for
    225. 225.  getSize() Houston
    226. 226.  ...-
    227. 227.  sets
    228. 228.  Content-Length
    229. 229.  if
    230. 230.  not
    231. 231.  0-
    232. 232.  response
    233. 233.  filters
    234. 234.  are
    235. 235.  called
    236. 236.  Runtime...-
    237. 237.  asks
    238. 238.  MBW
    239. 239.  for
    240. 240.  getSize() Houston
    241. 241.  ...-
    242. 242.  sets
    243. 243.  Content-Length
    244. 244.  if
    245. 245.  not
    246. 246.  0-
    247. 247.  response
    248. 248.  filters
    249. 249.  are
    250. 250.  called-
    251. 251.  MBW
    252. 252.  writeTo()
    253. 253.  is
    254. 254.  called
    255. 255.  Runtime...-
    256. 256.  asks
    257. 257.  MBW
    258. 258.  for
    259. 259.  getSize() Houston
    260. 260.  ...-
    261. 261.  sets
    262. 262.  Content-Length
    263. 263.  if
    264. 264.  not
    265. 265.  0-
    266. 266.  response
    267. 267.  filters
    268. 268.  are
    269. 269.  called-
    270. 270.  MBW
    271. 271.  writeTo()
    272. 272.  is
    273. 273.  called-
    274. 274.  interceptors
    275. 275.  wrap
    276. 276.  around
    277. 277.  Runtime...-
    278. 278.  asks
    279. 279.  MBW
    280. 280.  for
    281. 281.  getSize() Houston
    282. 282.  ...-
    283. 283.  sets
    284. 284.  Content-Length
    285. 285.  if
    286. 286.  not
    287. 287.  0-
    288. 288.  response
    289. 289.  filters
    290. 290.  are
    291. 291.  called-
    292. 292.  MBW
    293. 293.  writeTo()
    294. 294.  is
    295. 295.  called-
    296. 296.  interceptors
    297. 297.  wrap
    298. 298.  around
    299. 299.  If
    300. 300.  they
    301. 301.  change
    302. 302.  content
    303. 303.  the
    304. 304.  length
    305. 305.  Runtime...-
    306. 306.  asks
    307. 307.  MBW
    308. 308.  for
    309. 309.  getSize() Houston
    310. 310.  ...-
    311. 311.  sets
    312. 312.  Content-Length
    313. 313.  if
    314. 314.  not
    315. 315.  0-
    316. 316.  response
    317. 317.  filters
    318. 318.  are
    319. 319.  called-
    320. 320.  MBW
    321. 321.  writeTo()
    322. 322.  is
    323. 323.  called-
    324. 324.  interceptors
    325. 325.  wrap
    326. 326.  around
    327. 327.  If
    328. 328.  they
    329. 329.  change
    330. 330.  content
    331. 331.  the
    332. 332.  lengthwon’t
    333. 333.  match!
    334. 334. 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
    335. 335. Houston,
    336. 336.  it’s
    337. 337.   us
    338. 338.  again...
    339. 339. public Object aroundReadFrom(ReaderInterceptorContext readCtx) { InputStream in = readCtx.getEntityStream(); readCtx.setInputStream(new GZIPInputStreamStream(in) ); Object entity = readCtx.proceed(); return entity;}
    340. 340. public Object aroundReadFrom(ReaderInterceptorContext readCtx) { if(! readCtx.getHeaders().getFirst(Content-Encoding) ... ){ // skip } InputStream in = readCtx.getEntityStream(); readCtx.setInputStream(new GZIPInputStreamStream(in) ); Object entity = readCtx.proceed(); return entity;}
    341. 341. public void aroundWriteTo(WriterInterceptorContext writeCtx) { OutputStream out = writeCtx.getOutputStream(); writeCtx.setOutputStream(new GZIPOutputStream(out)); writeCtx.proceed();}
    342. 342. public void aroundWriteTo(WriterInterceptorContext writeCtx) { // Check whether client said Accept-Encoding: gzip OutputStream out = writeCtx.getOutputStream(); writeCtx.setOutputStream(new GZIPOutputStream(out)); writeCtx.getHeaders().add(Content-Encoding , gzip); writeCtx.proceed();} Actually,
    343. 343.  it’s
    344. 344.  not
    345. 345.  even
    346. 346.   that
    347. 347.  easy
    348. 348.  because
    349. 349.  CE
    350. 350.  is
    351. 351.  an
    352. 352.   ordered
    353. 353.  list
    354. 354.  of
    355. 355.  tokens
    356. 356. Hands off!Messing with the
    357. 357. Buffering the Stream@Providerclass DigSigInterceptor implements WriterInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ctx.setOutputStream(buffer); ctx.proceed(); String signature = getSignature(buffer); ctx.getHeaders().putSingle(X-Signature,signature); outputStream.write(buffer); }}
    358. 358. Filters and Interceptors
    359. 359. Filters and Interceptors-Seven
    360. 360.  extension
    361. 361.  points
    362. 362.  (4
    363. 363.  +
    364. 364.  1
    365. 365.  +
    366. 366.  2)
    367. 367. Filters and Interceptors-Seven
    368. 368.  extension
    369. 369.  points
    370. 370.  (4
    371. 371.  +
    372. 372.  1
    373. 373.  +
    374. 374.  2)-@PreMatching
    375. 375.  filters
    376. 376. Filters and Interceptors-Seven
    377. 377.  extension
    378. 378.  points
    379. 379.  (4
    380. 380.  +
    381. 381.  1
    382. 382.  +
    383. 383.  2)-@PreMatching
    384. 384.  filters-Filters
    385. 385.  done
    386. 386.  before
    387. 387.  entity
    388. 388.  is
    389. 389.  streamed
    390. 390. Filters and Interceptors-Seven
    391. 391.  extension
    392. 392.  points
    393. 393.  (4
    394. 394.  +
    395. 395.  1
    396. 396.  +
    397. 397.  2)-@PreMatching
    398. 398.  filters-Filters
    399. 399.  done
    400. 400.  before
    401. 401.  entity
    402. 402.  is
    403. 403.  streamed-Stream
    404. 404.  not
    405. 405.  flowing
    406. 406.  through
    407. 407. Filters and Interceptors-Seven
    408. 408.  extension
    409. 409.  points
    410. 410.  (4
    411. 411.  +
    412. 412.  1
    413. 413.  +
    414. 414.  2)-@PreMatching
    415. 415.  filters-Filters
    416. 416.  done
    417. 417.  before
    418. 418.  entity
    419. 419.  is
    420. 420.  streamed-Stream
    421. 421.  not
    422. 422.  flowing
    423. 423.  through-Altering
    424. 424.  stream:
    425. 425.  handle
    426. 426.  with
    427. 427.  care
    428. 428. Filters and Interceptors-Seven
    429. 429.  extension
    430. 430.  points
    431. 431.  (4
    432. 432.  +
    433. 433.  1
    434. 434.  +
    435. 435.  2)-@PreMatching
    436. 436.  filters-Filters
    437. 437.  done
    438. 438.  before
    439. 439.  entity
    440. 440.  is
    441. 441.  streamed-Stream
    442. 442.  not
    443. 443.  flowing
    444. 444.  through-Altering
    445. 445.  stream:
    446. 446.  handle
    447. 447.  with
    448. 448.  care-Architectural
    449. 449.  mismatch
    450. 450.  -
    451. 451.  getSize()
    452. 452. Filters and Interceptors-Seven
    453. 453.  extension
    454. 454.  points
    455. 455.  (4
    456. 456.  +
    457. 457.  1
    458. 458.  +
    459. 459.  2)-@PreMatching
    460. 460.  filters-Filters
    461. 461.  done
    462. 462.  before
    463. 463.  entity
    464. 464.  is
    465. 465.  streamed-Stream
    466. 466.  not
    467. 467.  flowing
    468. 468.  through-Altering
    469. 469.  stream:
    470. 470.  handle
    471. 471.  with
    472. 472.  care-Architectural
    473. 473.  mismatch
    474. 474.  -
    475. 475.  getSize()
    476. 476.  now
    477. 477.  ignored
    478. 478. Filters vs. Interceptors
    479. 479. Filters vs. Interceptors Interceptors...
    480. 480. Filters vs. Interceptors Interceptors... -
    481. 481.  Can
    482. 482.  write
    483. 483.  before
    484. 484. Filters vs. Interceptors Interceptors... -
    485. 485.  Can
    486. 486.  write
    487. 487.  before
    488. 488.  
    489. 489.  and
    490. 490.  after
    491. 491. Filters vs. Interceptors Interceptors... -
    492. 492.  Can
    493. 493.  write
    494. 494.  before
    495. 495.  
    496. 496.  and
    497. 497.  after -
    498. 498.  see
    499. 499.  stream
    500. 500.  afterwards
    501. 501. Filters vs. Interceptors Interceptors... -
    502. 502.  Can
    503. 503.  write
    504. 504.  before
    505. 505.  
    506. 506.  and
    507. 507.  after -
    508. 508.  see
    509. 509.  stream
    510. 510.  afterwards -
    511. 511.  know
    512. 512.  user
    513. 513.  entity
    514. 514.  type
    515. 515. Filters vs. Interceptors Interceptors... -
    516. 516.  Can
    517. 517.  write
    518. 518.  before
    519. 519.  
    520. 520.  and
    521. 521.  after -
    522. 522.  see
    523. 523.  stream
    524. 524.  afterwards -
    525. 525.  know
    526. 526.  user
    527. 527.  entity
    528. 528.  type -
    529. 529.  only
    530. 530.  invoked
    531. 531.  when
    532. 532. Filters vs. Interceptors Interceptors... -
    533. 533.  Can
    534. 534.  write
    535. 535.  before
    536. 536.  
    537. 537.  and
    538. 538.  after -
    539. 539.  see
    540. 540.  stream
    541. 541.  afterwards -
    542. 542.  know
    543. 543.  user
    544. 544.  entity
    545. 545.  type -
    546. 546.  only
    547. 547.  invoked
    548. 548.  when
    549. 549.  
    550. 550.  entity
    551. 551.  accessed
    552. 552. Priorities
    553. 553. Priorities@Provider@BindingPriority(BindingPriority.AUTHENTICATION)public class AuthFilter implements ContainerRequestFilter {...}@Provider@BindingPriority(BindingPriority.HEADER_DECORATOR)public class CacheCtrlFilter implements ContainerRequestFilter {..}
    554. 554. Binding Prioritiespublic 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();}
    555. 555. Reverse
    556. 556.  Order
    557. 557. Reverse
    558. 558.  Order
    559. 559. Chains Are Independent@Provider @PreMatching This
    560. 560.  will
    561. 561.  be
    562. 562.  called
    563. 563.  first!@BindingPriority(BindingPriority.HEADER_DECORATOR)public class AuthFilter implements ContainerRequestFilter { ...}@Provider@BindingPriority(BindingPriority.AUTHENTICATION)public class CacheCtrlFilter implements ContainerRequestFilter { ...}
    564. 564. Priorities-
    565. 565.  Ordering
    566. 566.  by
    567. 567.  binding
    568. 568.  priorities-
    569. 569.  Apply
    570. 570.  per
    571. 571.  chain!
    572. 572. FILTER INTERCEPTORBINDING
    573. 573. Default server sidebinding of filtersand interceptors is Anyone
    574. 574.  can
    575. 575.  see
    576. 576.  me! @Provider public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { ... }
    577. 577. What
    578. 578.  if
    579. 579.  I
    580. 580.  don’t
    581. 581.  want
    582. 582.  them
    583. 583.  applied
    584. 584.   globally?
    585. 585. @NameBinding@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface Logged { } What
    586. 586.  if
    587. 587.  I
    588. 588.  don’t
    589. 589.   want
    590. 590.  them
    591. 591.  applied
    592. 592.   globally?
    593. 593. @NameBinding@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface Logged { } What
    594. 594.  if
    595. 595.  I
    596. 596.  don’t
    597. 597.   want
    598. 598.  them
    599. 599.  applied
    600. 600.   globally?@Provider@Loggedpublic class LogFilter ...
    601. 601. @NameBinding@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface Logged { } What
    602. 602.  if
    603. 603.  I
    604. 604.  don’t
    605. 605.   want
    606. 606.  them
    607. 607.  applied
    608. 608.   globally?@Provider @Path(entries/{id})@Logged public class EntryResource {public class LogFilter ... @GET @Logged public Entry getEntry() { ... } }
    609. 609. @NameBinding@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface Cacheable {        String cc() default public, must-revalidate;} And
    610. 610.  if
    611. 611.  I
    612. 612.  need
    613. 613.  to
    614. 614.  pass
    615. 615.   information?
    616. 616. @NameBinding@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface Cacheable {        String cc() default public, must-revalidate;} @GET @Cacheable(cc=public, maxAge=3600) public Report getHourlyReport() { ... } And
    617. 617.  if
    618. 618.  I
    619. 619.  need
    620. 620.  to
    621. 621.  pass
    622. 622.   information?
    623. 623. @Provider@Cacheablepublic class CacheControlDecorator implements ContainerResponseFilter { public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { for (Annotation a : responseContext.getEntityAnnotations()) { if (a.annotationType() == Cacheable.class) { String cc = ((Cacheable) a).cc(); responseContext.getHeaders().add(Cache-Control, cc); } } }} Nice
    624. 624.  pattern!
    625. 625. But what if youwant to bundle
    626. 626. @Providerpublic class LoggingAndAuditFeature implements DynamicFeature { void configure(ResourceInfo resourceInfo,Configurable configurable) { if(MyResource.class.isAssignableFrom(resourceInfo.getResourceClass()) resourceInfo.getResourceMethod().isAnnotationPresent(GET.class)) { configurable.register(new LoggingFilter()); } if(OtherResource.class.isAssignableFrom(resourceInfo.getResourceClass()) resourceInfo.getResourceMethod().isAnnotationPresent(GET.class)) { configurable.register(AuditFilter.class); } // more branches, deciding what to register for *this* resource/method }}
    627. 627. configurable.register(AuditFilter.class);configurable.register(new LoggingFilter()); Wait
    628. 628.  a
    629. 629.  minute! Did
    630. 630.  you
    631. 631.  see
    632. 632.  that?
    633. 633. On the client-side Nobody
    634. 634.  can
    635. 635.  see
    636. 636.  me
    637. 637.  providers only unless
    638. 638.  you
    639. 639.  register()
    640. 640.  me!take effect if @Provider public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { ... }
    641. 641. You
    642. 642.  can
    643. 643.  .register(provider)
    644. 644.  on
    645. 645.  each
    646. 646.  of
    647. 647.  the
    648. 648.  4
    649. 649.  client
    650. 650.   API
    651. 651.  classes client.register(LogFilter.class); customerWt.register(new CustomerMBR()); invocation.register(GzipInterceptor.class); invocationBuilder.register( ... );
    652. 652. Fluent
    653. 653.  API,
    654. 654.  returning
    655. 655.  the
    656. 656.  same
    657. 657.   instance. customerWt .register(CustomerMBR.class) .register(CustomerMBW.class) .register(AuditFilter.class);
    658. 658. But what if youwant to bundle
    659. 659. public class ClientCacheFeature implements Feature { public configure(Configuration configuration) { configuration.register(ClientCacheInterceptor.class); configuration.register(ClientCacheHeaderFilter.class); configuration.setProperty(ClientCacheFeature.CACHE_SIZE,100); }}Client client = clientFactory.newClient();client.register(ClientCacheFeature.class); Feature
    660. 660.  ==
    661. 661.  combination
    662. 662.  of
    663. 663.  providers.
    664. 664. Binding .register()
    665. 665. Binding .register()-
    666. 666.  Named
    667. 667.  binding,
    668. 668.  dynamic
    669. 669.  features
    670. 670. Binding .register()-
    671. 671.  Named
    672. 672.  binding,
    673. 673.  dynamic
    674. 674.  features-
    675. 675.  register(),
    676. 676.  features
    677. 677. Binding .register()-
    678. 678.  Named
    679. 679.  binding,
    680. 680.  dynamic
    681. 681.  features-
    682. 682.  register(),
    683. 683.  features-
    684. 684.  Dedicated
    685. 685.  provider
    686. 686.  instances
    687. 687.  when
    688. 688. Binding .register()-
    689. 689.  Named
    690. 690.  binding,
    691. 691.  dynamic
    692. 692.  features-
    693. 693.  register(),
    694. 694.  features-
    695. 695.  Dedicated
    696. 696.  provider
    697. 697.  instances
    698. 698.  when
    699. 699.  
    700. 700.  configuring
    701. 701. Async API I
    702. 702.  like
    703. 703.  them
    704. 704.   threads
    705. 705.  in
    706. 706.  separate
    707. 707.   pools! ADMIN Long- HTTP RunninWorker gThread Thread s
    708. 708. @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
    709. 709.  gave
    710. 710.  you
    711. 711.   }); @Suspended
    712. 712.  and
    713. 713.   // Return and handle next // request immediately AsyncResponse!}
    714. 714. @GET@Path(large-thing)@Asynchronouspublic void getLargeThing(@Suspended AsyncResponse ar) { // long running: building the large thing ar.resume(THE LARGE THING);} @Asynchronous
    715. 715.   rocks!
    716. 716. @GET@Path(large-thing)@Asynchronouspublic void getLargeThing(@Suspended AsyncResponse ar) { // long running: building the large thing ar.resume(THE LARGE THING);} I
    717. 717.  tellya! @Asynchronous
    718. 718.   rocks!
    719. 719. @GET @Path(large-thing)public void getLargeThing(@Suspended AsyncResponse ar) { ar.setTimeout(15, SECONDS); ar.setTimeoutHandler(new TimeoutHandler() { public void handleTimeout(AsyncResponse ar) { ar.resume(Operation timed out -- please try again); }); } Executors.newSingleThreadExecutor().submit(new Runnable() { public void run() { // long running: building the large thing ar.resume(LARGE THING); } });}
    720. 720. @GET @Path(large-thing)public void getLargeThing(@Suspended AsyncResponse ar) { ar.setTimeout(15, SECONDS); ar.setTimeoutHandler(new TimeoutHandler() { public void handleTimeout(AsyncResponse ar) { log(Still large-thing not finished); ar.setTimeout(15, SECONDS); }); } Executors.newSingleThreadExecutor().submit(new Runnable() { public void run() { // long running: building the large thing ar.resume(LARGE THING); } });}
    721. 721. Push @POST @Path(stock/APPL) public void subs(@Suspended AsyncResponse ar) { if(!subscriberQueue.offer(ar)){Architectures ar.resume(Response.status(503). header(Retry-After,10).build()); } } -subscribe-
    722. 722. Push public void notify( @Observes StockEvent event) { AsyncResponse ar = subsQueue.poll(); while(ar != null) {Architectures ar.resume(event); ar = subscriberQueue.poll(); } } -notify-
    723. 723. Long-Polling ClientInvocation poll = client .target(http://example/stocks/APPL) .register(StockQuoteMBR.class) .request(application/stockquote) .buildGet();while( keepLongPolling ) { StockQuote quote = poll.invoke(StockQuote.class); gui.update(quote);}
    724. 724. Async in Client APIcalendarWt.request(text/calendar).async().get( new InvocationCallbackCalendarData() { You
    725. 725.  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
    726. 726.   they
    727. 727.  make
    728. 728.  me
    729. 729.   async,
    730. 730.  too?
    731. 731. Async
    732. 732. Async-Better
    733. 733.  thread
    734. 734.  pooling
    735. 735. Async-Better
    736. 736.  thread
    737. 737.  pooling-Response
    738. 738.  parking
    739. 739. Async-Better
    740. 740.  thread
    741. 741.  pooling-Response
    742. 742.  parking-Long
    743. 743.  polling
    744. 744. Async-Better
    745. 745.  thread
    746. 746.  pooling-Response
    747. 747.  parking-Long
    748. 748.  polling-
    749. 749.  Callbacks,
    750. 750.  Timeouts
    751. 751. Async-Better
    752. 752.  thread
    753. 753.  pooling-Response
    754. 754.  parking-Long
    755. 755.  polling-
    756. 756.  Callbacks,
    757. 757.  Timeouts
    758. 758. Async-Better
    759. 759.  thread
    760. 760.  pooling-Response
    761. 761.  parking-Long
    762. 762.  polling-
    763. 763.  Callbacks,
    764. 764.  Timeouts-Parallel
    765. 765.  requests
    766. 766. Async-Better
    767. 767.  thread
    768. 768.  pooling-Response
    769. 769.  parking-Long
    770. 770.  polling-
    771. 771.  Callbacks,
    772. 772.  Timeouts-Parallel
    773. 773.  requests-Callbacks
    774. 774.  or
    775. 775.  FutureT
    776. 776. Need helpbuilding links?
    777. 777. @Path(entries/{id})public class EntryResource { @PathParam(id) String id; @GET public Entry getEntry() { ... } @GET @Path(comments) public Comments getComments() { ... }}
    778. 778. @Path(entries/{id})public class EntryResource { @PathParam(id) String id; @GET public Entry getEntry() { ... } @GET @Path(comments) public Comments getComments() { ... }}ub1 = UriBuilder.fromResource(EntryResource.class);ub2 = UriBuilder.fromMethod(EntryResource.class,getComments);
    779. 779. @Path(entries/{id})public class EntryResource { @PathParam(id) String id; @GET public Entry getEntry() { ... } @GET @Path(comments) public Comments getComments() { ... }}ub1 = UriBuilder.fromResource(EntryResource.class);ub2 = UriBuilder.fromMethod(EntryResource.class,getComments);uri = ub2.build(42); // entries/42/comments
    780. 780. lb1 = LinkBuilder .fromResource(EntryResource.class,edit);lb2 = LinkBuilder .fromMethod(EntryResource.class,getComments,comments);
    781. 781. lb1 = LinkBuilder .fromResource(EntryResource.class,edit);lb2 = LinkBuilder .fromMethod(EntryResource.class,getComments,comments);link = lb1.build(42);
    782. 782. lb1 = LinkBuilder .fromResource(EntryResource.class,edit);lb2 = LinkBuilder .fromMethod(EntryResource.class,getComments,comments);link = lb1.build(42);String headerValue = link.toString();
    783. 783. lb1 = LinkBuilder .fromResource(EntryResource.class,edit);lb2 = LinkBuilder .fromMethod(EntryResource.class,getComments,comments);link = lb1.build(42);String headerValue = link.toString();// yields: entries/42; rel=edit
    784. 784. Not Just in Resources@Providerpublic 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()); }}
    785. 785. Linking
    786. 786. Linking-
    787. 787.  From
    788. 788.  resource
    789. 789.  or
    790. 790.  method
    791. 791. Linking-
    792. 792.  From
    793. 793.  resource
    794. 794.  or
    795. 795.  method-
    796. 796.  Are
    797. 797.  relative
    798. 798.  links
    799. 799.  indeed
    800. 800.  useful?
    801. 801. Linking-
    802. 802.  From
    803. 803.  resource
    804. 804.  or
    805. 805.  method-
    806. 806.  Are
    807. 807.  relative
    808. 808.  links
    809. 809.  indeed
    810. 810.  useful?
    811. 811. Wouldn’t
    812. 812.  DI
    813. 813.   in
    814. 814.  subresource
    815. 815.  locators
    816. 816.   make
    817. 817.  this
    818. 818.  darn
    819. 819.  mission
    820. 820.   easier?One more thing... Nicht gut - nimm ein image
    821. 821. @Path(entries)public class EntriesResource { Subresource @Path({id}) public EntryResource findEntry(@PathParam(id) String id) { return new EntryResource(id); }}
    822. 822. @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() { ... }}
    823. 823. @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!}
    824. 824. @Path(entries)public class EntriesResource { @Context ResourceContext rc; Subresource @Path({id}) public EntryResource findEntry(@PathParam(id) String id) { return rc.initResource(new EntryResource(id)); }}
    825. 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)); }}public class EntryResource { @Context HttpHeaders headers; public EntryResource(String id) { ... } @GET public Entry getEntry() { return new Entry(); }}
    826. 826. @Providerclass TestFilter implements ContainerRequestFilter { @Context ResourceContext rc; void filter(ContainerRequestContext requestContext) ... { Widget w = rc.getResource(Widget.class); Gadget g = rc.initResource(new Gadget(...)); }} And
    827. 827.  what
    828. 828.  about
    829. 829.   DI
    830. 830.  in
    831. 831.  filters?
    832. 832. public class Widget { @PathParam(id) String id; public Widget(@HeaderParam(Referer) String referer) { ... }}public class Gadget { @PathParam(id) String id; @HeaderParam(Referer) String referer public Gadget(int foo) { ... }} Nice!
    833. 833.  DI
    834. 834.  anywhere.
    835. 835. @Providerclass 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(); }}
    836. 836. 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 }}
    837. 837. @Provider @PreMatchingclass 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 }}
    838. 838. ResourceContext
    839. 839. ResourceContext-
    840. 840.  DI
    841. 841.  for
    842. 842.  subresource
    843. 843.  locators
    844. 844. ResourceContext-
    845. 845.  DI
    846. 846.  for
    847. 847.  subresource
    848. 848.  locators-
    849. 849.  Even
    850. 850.  better:
    851. 851.  DI
    852. 852.  for
    853. 853.  any
    854. 854.  instance
    855. 855. ResourceContext-
    856. 856.  DI
    857. 857.  for
    858. 858.  subresource
    859. 859.  locators-
    860. 860.  Even
    861. 861.  better:
    862. 862.  DI
    863. 863.  for
    864. 864.  any
    865. 865.  instance-
    866. 866.  e.g.
    867. 867.  stream
    868. 868.  filters
    869. 869. 2.0 - Wrapping Up
    870. 870. 2.0 - Wrapping Up-
    871. 871.  Consolidation
    872. 872.  (Client
    873. 873.  API,
    874. 874.  Filters,
    875. 875.  Interceptors)
    876. 876. 2.0 - Wrapping Up-
    877. 877.  Consolidation
    878. 878.  (Client
    879. 879.  API,
    880. 880.  Filters,
    881. 881.  Interceptors)-
    882. 882.  Invocation,
    883. 883.  InvocationBuilder
    884. 884. 2.0 - Wrapping Up-
    885. 885.  Consolidation
    886. 886.  (Client
    887. 887.  API,
    888. 888.  Filters,
    889. 889.  Interceptors)-
    890. 890.  Invocation,
    891. 891.  InvocationBuilder-
    892. 892.  Filters/Interceptors
    893. 893. 2.0 - Wrapping Up-
    894. 894.  Consolidation
    895. 895.  (Client
    896. 896.  API,
    897. 897.  Filters,
    898. 898.  Interceptors)-
    899. 899.  Invocation,
    900. 900.  InvocationBuilder-
    901. 901.  Filters/Interceptors-
    902. 902.  Advice:
    903. 903.  careful
    904. 904.  with
    905. 905.  altering
    906. 906.  stream
    907. 907. 2.0 - Wrapping Up-
    908. 908.  Consolidation
    909. 909.  (Client
    910. 910.  API,
    911. 911.  Filters,
    912. 912.  Interceptors)-
    913. 913.  Invocation,
    914. 914.  InvocationBuilder-
    915. 915.  Filters/Interceptors-
    916. 916.  Advice:
    917. 917.  careful
    918. 918.  with
    919. 919.  altering
    920. 920.  stream-
    921. 921.  Async
    922. 922.  support
    923. 923.  (pooling,
    924. 924.  Comet
    925. 925.  arch.,
    926. 926.  async
    927. 927.  client)
    928. 928. 2.0 - Wrapping Up-
    929. 929.  Consolidation
    930. 930.  (Client
    931. 931.  API,
    932. 932.  Filters,
    933. 933.  Interceptors)-
    934. 934.  Invocation,
    935. 935.  InvocationBuilder-
    936. 936.  Filters/Interceptors-

    ×