Upload
buitu
View
223
Download
0
Embed Size (px)
Citation preview
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
What’sNewinJAX-RS2.1?CON3625
DavidDelabassée@delabasseeJavaandContainerNaMvePlaOorm-OracleOctober,2017
1
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
SafeHarborStatementThefollowingisintendedtooutlineourgeneralproductdirecMon.ItisintendedforinformaMonpurposesonly,andmaynotbeincorporatedintoanycontract.Itisnotacommitmenttodeliveranymaterial,code,orfuncMonality,andshouldnotberelieduponinmakingpurchasingdecisions.Thedevelopment,release,andMmingofanyfeaturesorfuncMonalitydescribedforOracle’sproductsremainsatthesolediscreMonofOracle.
3
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS
• JAX-RS2.0– JSR339,leadbySanMagoPericasgeertsen&MarekPotociar– JavaEE7
• JAX-RS2.1– JSR370,leadbySanMagoPericasgeertsen&PavelBucek– JavaEE8
• JavaEE&JavaSE
JavaAPIforRESTfulWebServices
5
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS
• ReferenceImplementaMon– Jersey• h`ps://jersey.github.io
• Butalso– RESTEasy– Restlet– ApacheCXF– ApacheWink– IBMJAX-RS,…
JavaAPIforRESTfulWebServices
6
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Clientclient=ClientBuilder.newClient();WebTargettarget=client.target("http://weath.er/api").queryParam("city","Paris");Forecastforecast=target.request().get(Forecast.class);//…client.close();
JAX-RSClientAPI
7
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• FluentAPI– ClientBuilderèClientèWebTargetèRequestbuildingèResponse
javax.ws.rs.client.Clientinterface
8
List<Forecast>forecast=ClientBuilder.newClient().target("http://weath.er/cities").request().accept("application/json").header("Foo","bar").get(newGenericType<List<Forecast>>(){});
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• Synchronousinvoker
• Asynchronousinvoker
JAX-RS2.0Invokers
9
Stringcity=client.target("http://locati.on/api").queryParam("city","Paris").request().get(String.class);
Future<String>fCity=client.target("http://locati.on/api").queryParam("city","Paris").request().async().get(String.class);
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvocaJon
11
Future<String>fCity=client.target("http://locati.on/api").queryParam("city","Paris").request().async().get(String.class);
Stringcity=fCity.get();
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvocaJon
12
Future<String>fCity=client.target("http://locati.on/api").queryParam("city","Paris").request().async().get(String.class);try{
Stringcity=fCity.get(5,TimeUnit.SECONDS);
}catch(TimeoutExceptiontimeout){
//…
}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPIAsynchronousinvocaJon
13
//SetClientProperties.CONNECT_TIMEOUT&READ_TIMEOUTFuture<String>fCity=client.target("http://locati.on/api").queryParam("city","Paris").request().async().get(String.class);while(!fCity.isDone()){
//responsehasn'tbeenreceivedyet
}
Stringcity=fCity.get();
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
• InvocaMonCallbackInterface– javax.ws.rs.client.InvocationCallback<RESPONSE>
• ContainerwillreceiveasyncprocessingeventsfromaninvocaMon– completed(RESPONSEresponse)– failed(Throwablethrowable)
AsynchronousinvocaJon
14
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
WebTargetmyResource=client.target("http://examp.le/api/read");Future<Customer>future=myResource.request(MediaType.TEXT_PLAIN)
.async().get(newInvocationCallback<Customer>(){ @Override publicvoidcompleted(Customercustomer){ //dosomethingwiththecustomer } @Override publicvoidfailed(Throwablethrowable){ //Oops! }});
…
InvocaJonCallback
15
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
TheTravelService
• Customerdetails:150ms• RecommendeddesMnaMons:250ms• PricecalculaMonforacustomeranddesMnaMon:170ms(each)• WeatherforecastforadesMnaMon:330ms(each)
Synchronous
17
5400ms
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
TheTravelService
20
destination.path("destination").request().header("Rx-User","Async").async().get(newInvocationCallback<List<Destination>>(){@Overridepublicvoidcompleted(finalList<Destination>destination){finalCountDownLatchinnerLatch=newCountDownLatch(destination.size());finalMap<String,Forecast>forecasts=Collections.synchronizedMap(newHashMap<>());for(finalDestinationdest:destination){forecast.resolveTemplate("dest",dest.getDestination()).request().async().get(newInvocationCallback<Forecast>(){@Overridepublicvoidcompleted(finalForecastforecast){forecasts.put(dest.getDestination(),forecast);innerLatch.countDown();}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
TheTravelService
21
//cont.@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.|
JAX-RSClientAPI
NewJAX-RSReacJveInvoker
22
//JAX-RS2.0Responseresponse=ClientBuilder.newClient().target(someEndPoint).request().get();
Future<Response>fResponse=ClientBuilder.newClient().target(someEndPoint).request().async().get();//JAX-RS2.1CompletionStage<Response>csResponse=ClientBuilder.newClient().target(someEndPoint).request().rx().get();
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
23
NewJAX-RSReacJveInvoker
//getIPCompletionStage<JsonObject>cfIp=client.target("http://api.ipify.org/")
.queryParam("format","json").request() .rx() .get(JsonObject.class);
//getIPlocationCompletionStage<JsonObject>cfLoc=client.target("https://ipvigilante.com")
.path(ip.getString("ip")).request() .rx() .get(JsonObject.class);
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSClientAPI
24
NewJAX-RSReacJveInvoker
CompletionStage<JsonObject>cfIp=client.target("http://api.ipify.org/") .queryParam("format","json").request() .rx() .get(JsonObject.class);
Function<JsonObject,CompletionStage<JsonObject>>function=ip
->client.target("https://ipvigilante.com") .path(ip.getString("ip")).request() .rx() .get(JsonObject.class);
Consumer<JsonObject>consumer=location->async.resume(locDetails);
cfIp.thenCompose(function).thenAccept(consumer);
h`ps://github.com/delabassee/EE8_JAX-RS_RX
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
TheTravelService
25
h`ps://github.com/jersey/jersey/tree/master/examples/rx-client-webapp
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
26
Invokers
Sync Async RXPerformanceandscalability ✗✗ ✔ ✔Easytodevelopandmaintain ✔ ✗ ✔
…complexworkflow ✗ ✗ ✔…errorhandling ✗ ✗ ✔
LeveragenewJavaSEfeature ✗ ✗ ✔
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RSReacMveExtensions
“AllJAX-RSimplementaMonsMUSTsupportaninvokerforCompleMonStage.AddiMonally,JAX-RSimplementaMonsMAYsupportotherreacMveAPIsusinganextensionbuiltintotheClientAPI.”• Jersey– CompleMonStageRxInvoker(Default)– RxListenableFutureInvoker–Guava– RxObservableInvoker–RxJava– RxFlowableInvoker–RxJava2
27
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
LongRunningOperaMonJAX-RS2.0-AsyncResponse
28
@GETpublicvoidpopulateDestination(@SuspendedfinalAsyncResponseasyncResponse){
executor.submit(newRunnable(){publicvoidrun(){JsonObjectdestination=executeLongRunningOpToGetDest();
asyncResponse.resume(destination);}});
}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
LongRunningOperaMon
29
JAX-RS2.0-AsyncResponse
@GETpublicvoidpopulateDestination(@SuspendedfinalAsyncResponseasyncResponse){CompletionStage<JsonObject>destinationCS=client.target("destination") .queryParam("format","json").request() .rx()
.get(JsonObject.class);destinationCS.thenApply(unmarhsallDestination).thenApply(populateDestination).thenAccept(asyncResponse::resume);
}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
LongRunningOperaMon
30
JAX-RS2.1-CompleJonStage
@GETpublicCompletionStage<Destination>populateDestination(){CompletionStage<JsonObject>destinationCS=client.target("destination") .queryParam("format","json").request() .rx()
.get(JsonObject.class);returndestinationCS.thenApply(unmarhsallDestination).thenApply(populateDestination);
}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
LongRunningOperaMon
31
Client Server
@Suspended
AsyncResponse.resume(…)
LongrunningoperaMon…
Request
Response
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
ExecutorServices
32
• UsedforAsynchronousinvocaMons• SpecifiedwhencreaMngtheClientcontainer– ClientBuilder.executorService(ExecutorService)– ClientBuilder.scheduledExecutorService(ScheduledExecutorService)
• UseManagedExecutorServiceandManagedScheduledExecutorServicewhen"ConcurrencyUMliMesforJavaEE"issupported– E.g.JavaEEfullplaOorm
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
• WHATWGstandard• Persistent,one-waycommunicaMonchannel• Textprotocol,specialmediatype"text/event-stream"• ServercansendmulMplemessages(events)toaclient• Cancontainid,name,comment,retryinterval
34
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
• Supportedinallmodernbrowsers
• JavaScriptAPI
35
h`ps://developer.microsot.com/en-us/microsot-edge/plaOorm/status/serversenteventseventsource/
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
36
• javax.ws.rs.sse.SseEventinterface– EventsproperMes• ID• Name• Comment• Reconnectinterval
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
37
• OutboundSseEvent– Server-siderepresentaMonofaServer-Sentevent– OutboundSseEvent.Builder()
• InboundSseEvent– Client-siderepresentaMonofaServer-Sentevent
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvents
38
• 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();}
Server-side
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
Server-SentEvent
39
Clientside
• SseEventSource– ClientforprocessingincomingServer-SentEvents
WebTargettarget=client.target("http://…");try(SseEventSourcesource=SseEventSource.target(target).reconnectingEvery(5,SECONDS).build()){source.register(System.out::println);//InboundSSEventconsumer...source.open();}catch(InterruptedExceptione){//Ooops}
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
• WhenJSON-Pissupported– MUSTsupportenMtyprovidersforJsonValueanditssub-types• JsonValue,JsonStructure,JsonObject,JsonArray,JsonStringandJsonNumber
• WhenJSON-Bissupported– MUSTsupportenMtyprovidersforallJavatypessupportedbyJSON-BincombinaMonwithfollowingmediatypes• applicaMon/json,text/json&Mediatypesmatching*/jsonor*/*+json
• WhenbothJSON-PandJSON-Baresupported– EnMtyprovidersforJSON-BtakeprecedenceforalltypesexceptJsonValueanditssub-types
41
JSONsupport
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
• JSON-B&JSON-Psupport• @PATCHsupport• @Priorityforallproviders• Allowsub-resourcelocatorstoreturnclassesaswell• ClarificaMons,…
42
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
• JSR370– JavaEE8
• Async– NewReacMveClientAPI– Newmethodforpausingresquestprocessing
• Server-SentEventsupport• JSON-P&JSON-Bsupport• …
JavaAPIforRESTfulWebServices
44
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
• Jersey2.26– h`ps://jersey.github.io
• ApacheCXF3.2.0– h`p://cxf.apache.org/
• RESTEasy3.?–soon!– h`p://resteasy.jboss.org
• …
JavaAPIforRESTfulWebServices
45
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JavaEE8–ModernizaMon&SimplificaMon
46
CDI2.0
JSON-B1.0(*)
Security1.0(*)
BeanValidaJon2.0
JSF2.3
Servlet4.0
JSON-P1.1
JAX-RS2.1 ReacMveClientAPI,Server-SentEvents,…
HTTP/2,ServerPush,…
Java<->JSONbinding
UpdatestoJSONstandards,JSONCollectors,…
AsyncEvent,Observersordering,SEsupport,…
EmbraceJavaSE8,newconstraints,…
ImprovedCDI,WebSocket,SE8integraMon,…
PortableIdenMtyStore,AuthenMcaMon&SecurityContext
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
EclipseEnterpriseforJava-EE4JMovingJavaEEtoEclipseFoundaJon
47
Technology
Communityand
VendorsSponsorship
ü Nimbleü Flexibleü Openü CompaMble
EnterpriseforJava
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1
• Resources– h`ps://jcp.org/en/jsr/detail?id=370– h`ps://javaee.groups.io/g/jaxrs-spec/– h`ps://github.com/jax-rs– h`ps://jersey.github.io/documentaMon/latest/index.html– h`ps://github.com/jersey/– h`ps://docs.oracle.com/javaee/8/tutorial/index.html
JavaAPIforRESTfulWebServices
48
Copyright©2017,Oracleand/oritsaffiliates.Allrightsreserved.|
JAX-RS2.1Dependencies
49
• API<groupId>javax.ws.rs</groupId><artifactId>javax.ws.rs-api</artifactId><version>2.1</version><groupId>javax</groupId> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <artifactId>javaee-web-api</artifactId><version>8.0</version> <version>8.0</version>
• Jersey– h`ps://jersey.github.io/documentaMon/latest/modules-and-dependencies.html