Date post: | 22-Jan-2018 |
Category: |
Software |
Upload: | david-delabassee |
View: | 545 times |
Download: | 1 times |
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
DavidDelabassee@delabasseeOracleMay2017
JAX-RS2.1Reloaded
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS
• StandardbasedRESTfulframework– JAX-RS2.0–JSR339(*)– JAX-RS2.1–JSR370– Jersey,JBossRESTEasy,Restlet,ApacheCXF,ApacheWink,IBMJAX-RS,…
• JavaSEandJavaEE
2
JavaAPIforRESTfulWebServices
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 3
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
SafeHarborStatementThefollowingisintendedtooutlineourgeneralproductdirec[on.Itisintendedforinforma[onpurposesonly,andmaynotbeincorporatedintoanycontract.Itisnotacommitmenttodeliveranymaterial,code,orfunc[onality,andshouldnotberelieduponinmakingpurchasingdecisions.Thedevelopment,release,and[mingofanyfeaturesorfunc[onalitydescribedforOracle’sproductsremainsatthesolediscre[onofOracle.
4
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Client-side
Confiden[al–OracleInternal/Restricted/HighlyRestricted 5
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• FluentAPI– ClientBuilderèClientèWebTargetè…èRequestbuildingèResponse
• Client– Clientsidecontainer– Customizable• Keystore,sslContext,Timeout,etc.• Setexecutorservice(2.1)– ClientBuilder.executorService(…);
javax.ws.rs.client.Clientinterface
6
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• WebTarget– TargetremoteURI– Buildfromaclient– path()+resolveTemplates(),queryParam(),matrixParam(),…
• Requestinvoca[onbuilder– BuildfromaWebTarget– acceptXXX(),cookie(),header(),cacheControl(),…– HTTPmethods
javax.ws.rs.client.Clientinterface
7
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• ClientInstanceèWebTargetèRequestInvoca[on
javax.ws.rs.client.Clientinterface
8
Clientclient=ClientBuilder.newClient();List<Forecast>forecast=client.target("http://weath.er/cities").accept("application/json").header("Foo","bar").get(newGenericType<List<Forecast>>(){});
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• Synchronousinvoker
• Asynchronousinvoker
9
Stringcity=client.target("http://locati.on/api").queryParam("city","Paris").request().get(String.class);
Future<String>future=client.target("http://locati.on/api")….request().async().get(String.class);
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvoca:on
10
Future<String>future=client.target("http://locati.on/api")…
.request().async().get(String.class);Stringcity=future.get();
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvoca:on
11
Future<String>future=client.target("http://locati.on/api")…
.request().async().get(String.class);
try{
Stringcity=future.get(5,TimeUnit.SECONDS);
}catch(TimeoutExceptiontimeout){…}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvoca:on
12
Future<String>future=client.target("http://locati.on/api")…
.request().async().get(String.class);
while(!future.isDone()){//responsehasn'tbeenreceivedyet…}
Stringcity=f.get();…
//SetClientProperties.CONNECT_TIMEOUT&READ_TIMEOUT
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• Invoca[onCallbackInterface– javax.ws.rs.client.Invoca[onCallback<RESPONSE>
• Willreceivetheasynchronousprocessingeventsfromaninvoca[on– completed(RESPONSEresponse)– failed(Throwablethrowable)
13
Asynchronousinvoca:on
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
14
Invoca:onCallback…WebTargetmyResource=client.target("http://examp.le/api/read");Future<Customer>future=myResource.request(MediaType.TEXT_PLAIN).async().get(newInvocationCallback<Customer>(){
@Overridepublicvoidcompleted(Customercustomer){//dosomethingwiththegivencustomer}
@Overridepublicvoidfailed(Throwablethrowable){//Oops!}
});
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 15
TheTravelService
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 16
TheTravelServicedestination.path("recommendedDestinations").request().header("Rx-User","...").async().get(newInvocationCallback<List<Destination>>(){@Overridepublicvoidcompleted(finalList<Destination>recommended){finalCountDownLatchinnerLatch=newCountDownLatch(recommended.size());finalMap<String,Forecast>forecasts=Collections.synchronizedMap(newHashMap<>());for(finalDestinationdest:recommended){forecast.resolveTemplate("dest",dest.getDestination()).request().async().get(newInvocationCallback<Forecast>(){@Overridepublicvoidcompleted(finalForecastforecast){forecasts.put(dest.getDestination(),forecast);innerLatch.countDown();}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 17
JAX-RS2.0
@Overridepublicvoidfailed(finalThrowablethrowable){innerLatch.countDown();}});}
try{if(!innerLatch.await(10,TimeUnit.SECONDS)){//timeout}}catch(finalInterruptedExceptione){//Ooops,interrupted!}
//Continuewithprocessing…}
@Overridepublicvoidfailed(finalThrowablethrowable){//Recommendationerror}});
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 18
JAX-RS2.1
//JAX-RS2.1CompletionStage<Response>csResponse=ClientBuilder.newClient().target("http://example.com/api").request().rx().get();
Future<Response>fResponse=ClientBuilder.newClient().target("http://example.com/api").request().async().get();
Responseresponse=ClientBuilder.newClient().target("http://example.com/api").request().get();
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Comple[onStageinterface
• “Astageofapossiblyasynchronouscomputa[on,thatperformsanac:onorcomputesavalue.Ontermina[onastagemayinturntriggerotherdependentstages.”• Astage'sexecu[onmaybetriggeredbycomple[onofstage(s)– 1“then”,2“combine”or1of2“either”
• Doesthecomputa[ontakesanargumentandreturnsaresult?– “apply”Func[on,“accept”Consumeror“run”Runnable
• ...
19
hrps://docs.oracle.com/javase/8/docs/api/java/u[l/concurrent/Comple[onStage.html
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 20
JAX-RS2.1
CompletionStage<Number>csp=client.target("price/{destination}").resolveTemplate("destination","Paris").request().rx().get(Number.class);CompletionStage<String>csf=client.target("forecast/{destination}").resolveTemplate("destination","Paris").request().rx().get(String.class);newCs=cscsp.thenCombine(csf,(price,forecast)->reserveIfAfforadble(price,forecast));
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Demo
• TheTravelService
21
hrps://github.com/jersey/jersey/tree/master/examples/rx-client-webapp
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1Reac[veClientAPI
22
Sync Async RXPerformanceandscalability ✗✗ ✔ ✔Easytodevelopandmaintain ✔ ✗ ✔
…complexworkflow ✗ ✗ ✔…errorhandling ✗ ✗ ✔
LeveragenewJavaSEfeature ✗ ✗ ✔
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• RESTClientSidecontainer• Synchronous– javax.ws.rs.client.SyncInvokerinterface– Defaultinvoker
• Asynchronous– javax.ws.rs.client.AsyncInvokerinterface– async()invoker– Mightblock!– Invoca[onCallback
23
Summary
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1Reac[veClientAPI• NewAsyncReac[veinvoker– javax.ws.rs.client.RxInvokerinterface
• Reac[veInvokerProviders– JavaSE8Comple[onStage– Jersey• RxJava-rx.Observable• RxJava2-io.reac[vex.Flowable• Guava–ListenableFuture
• ClientBuilder.executorService(…);
24
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-side
Confiden[al–OracleInternal/Restricted/HighlyRestricted 25
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 26
Server-side@Path("/Item")publicclassItemResource{@Path("{id}")@Produces(MediaType.APPLICATION_JSON)publicItemResourcegetItemResource(@PathParam("id")Stringid){returnItemResource.getInstance(id);}@POST@Consumes(MediaType.APPLICATION_XML)@Produces(MediaType.APPLICATION_JSON)publicResponsecreateItem(@QueryParam("name")Stringname){//...returnResponse.status(Status.OK).entity(…).build();}}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.| 27
Server-sideAsync@Path("async/longRunning")publicclassItemResource{
@GETpublicvoidlongRunningOp(@SuspendedAsyncResponsear){
mes.execute(newRunnable(){@Overridepublicvoidrun(){try{//longrunningcomputation...ar.resume(Response.ok(...).build());}catch(InterruptedExceptionex){//Ooops!}}});...
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-sideAsync
• Asynchronousresponse– Providesmeansforasynchronousserversideresponseprocessing– Injectablevia@Suspended– Boundtotherequest
• Requestprocessing– Suspend– Resume– Configure– Cancel
28
AsyncResponseinterface
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-sideAsync
29
Newin2.1@Path("/async/longRunning")publicclassItemResource{
@GETpublicCompletionStage<String>longRunningOp(){CompletableFuture<String>cs=newCompletableFuture<>();executor.submit(newRunnable(){
publicvoidrun(){executeLongRunningOp();cs.complete("Helloasyncworld!");}});returncs;}...}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-sideAsync
30
Client Server
@Suspended
AsyncResponse.resume(…)
Longrunningopera[on…
Request
Response
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
LongrunningRESTopera[ons
è POST...longrunningopera[on...ç ‘201Created’+Loca[on
31
è POSTç ‘202Accepted’+TempLoca[on
è GETTempLoca[onç ‘200OK’(+ETA)…è GETTempLoca[onç ‘303SeeOther’+FinalLoca[on
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-sentEvents
• Persistent,one-waycommunica[onchannel• Textprotocol,specialmediatype"text/event-stream"• Servercansendmul[plemessages(events)toaclient• Cancontainid,name,commentretryinterval• Supportedinallmodernbrowsers
32
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
33
SSE
• SseEvent– ID,Name,Comment,…
• OutboundSseEvent– Server-siderepresenta[onofaServer-sentevent– OutboundSseEvent.Builder()
• InboundSseEvent– Client-siderepresenta[onofaServer-sentevent
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
34
SSE–Serverside
• SseEventSink– OutboundServer-SentEventsstream– SseBroadcaster
@GET@Path("sse")@Produces(MediaType.SERVER_SENT_EVENTS)publicvoideventStream(@ContextSseEventSinkeventSink,@ContextSSEsse){...eventSink.send(sse.newEvent("anevent"));eventSink.send(sse.newEvent("anotherevent"));...eventSink.close();}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
35
SSE–Clientside
• SseEventSource– ClientforprocessingincomingServer-SentEvents
SseEventSourcees=SseEventSource.target(SSE_target).reconnectingEvery(5,SECONDS).build();es.register(System.out::println);//InboundSseEventconsumeres.register(...);//Throwableconsumeres.open();...es.close();
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Wrap-up
Confiden[al–OracleInternal/Restricted/HighlyRestricted 36
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS
• JavaAPIforRESTfulWebServices– JAX-RS2.0–JSR339
• StandardbasedRESTfulframework– Server-sideandclient-side– JavaSEandJavaEE– Jersey,JBossRESTEasy,Restlet,ApacheCXF,ApacheWink,IBMJAX-RS,…
37
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1–JSR370
• Reac[veClientAPI• Server-sentEventssupport• JSON-B&JSON-P1.1support• Misc.– Providersordering– PassingincomingrequestLocaletoBV– SerableClientexecutorservice– ReturnaninstanceofComple[onStage<T>– …hrps://github.com/jax-rs/api/labels/2.1-candidate(tbc)
38
• Non-blockingIOsupport• MakeJAXBop[onal
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JavaEE8
39
BeanValida:on
CDI2.0
JSON-B1.0
Security1.0
BV2.0
JSF2.3
Servlet4.0
JSON-P1.1
JAX-RS2.1 Reac[veclientAPI,Server-sentevents,…
HTTP/2,serverpush,…
Java<->JSONbinding
UpdatestoJSONstandards,JSONCollectors,…
Asyncevent,eventpriority,SEsupport,…
EmbraceJavaSE8,newconstraints
ImprovedCDI,WebSocket,SE8integra[on,…
StandardizedIden[tyStore,Authen[ca[on,SecurityContext
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JavaEE8• Workinprogress– FinalRelease-Summer2017(plan)
• OpenSourceReferenceImplementa[ons– hrps://github.com/javaee– hrps://github.com/jersey
• Contribute!– AdoptAJSR
• Staytuned…– hrps://blogs.oracle.com/theaquarium/
40
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Resources
• JAX-RSspecifica[on– hrps://github.com/jax-rs/api
• Jersey– hrps://github.com/jersey
• Jersey–AsynchronousServicesandClients– hrps://jersey.github.io/documenta[on/latest/user-guide.html#async
• Comple[onStageJavadoc– hrps://docs.oracle.com/javase/8/docs/api/java/u[l/concurrent/Comple[onStage.html
41
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Q&A
Confiden[al–OracleInternal/Restricted/HighlyRestricted 42