Sei sulla pagina 1di 11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

Select a page

Feed
Links
Folder Organizer
CNJ Amazon Store
Il Blog su Alfresco di Francesco Corti
Solo Tablet
Java Job
JDevelopment
Downloads
Contact
Team
Chi siamo
Collaboratori
About
Libri
Twitter
Facebook
Google+
LinkedIn

Select a page

Programmazione
Java
Java 8
RxJava
Scala
Agile
Android

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

1/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

Android
Web
AngularJS
EJB
Javascript
JBoss
JSF
jQuery
Spring
Websphere

Programmazione
Java
Java 8
RxJava
Scala
Agile
Android
Web
AngularJS
EJB
Javascript
JBoss
JSF
jQuery
Spring
Websphere

RxJava: trasformare una chiamata REST in

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

2/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

RxJava: trasformare una chiamata REST in


un Observable
Pubblicato da Giampaolo Trapasso il 09/12/2014 in RxJava, Tutorial
Nel primo post su RxJava abbiamo esaminato i due componenti essenziali di questo framework:
Observable e Observer. In tutti gli esempi lObservable era generato usando una lista di oggetti. Ora
vedremo, invece, come sia possibile costruire un Observable che incapsula una chiamata REST e
integrarlo nella nostra catena di operatori, uno scenario molto comune soprattutto scrivendo
unapplicazione Android.
Nellarticolo precedente utilizzavamo un elenco di citt e ne stampavamo in console il nome e la finta
situazione meteo. Adesso otterremo i dati attuali utilizzando http://openweathermap.org/api, un sito
che offre delle semplici API REST per interrogare le condizioni atmosferiche attuali e future. Per
costruire il client ci affideremo Jersey e deserializzeremo la risposta JSON utilizzando Gson, una libreria
di cui abbiamo gi parlato in passato. Unalternativa che sostituisce entrambi, e che sicuramente vale la
pena di approfondire in un prossimo post, Retrofit
Dalla documentazione delle API si ricava che per conoscere le condizioni meteo correnti di una citt
come ad esempio Londra, lurl da invocare il seguente
http://api.openweathermap.org/data/2.5/weather?q=London e restituisce questa risposta.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

{
"coord":{
"lon":0.13,
"lat":51.51
},
"sys":{
"type":1,
"id":5091,
"message":0.1016,
"country":"GB",
"sunrise":1417592825,
"sunset":1417622031
},
"weather":[
{
"id":801,
"main":"Clouds",
"description":"fewclouds",
"icon":"02d"
}
],
"base":"cmcstations",
"main":{
"temp":279.66,
"pressure":1024,
"humidity":65,
"temp_min":278.15,
"temp_max":281.15
},
"wind":{
"speed":5.7,
"deg":10

33 },
http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

3/11

11/11/2015

33
34
35
36
37
38
39
40
41

RxJava:trasformareunachiamataRESTinunObservable

},
"clouds":{
"all":20
},
"dt":1417605604,
"id":2643743,
"name":"London",
"cod":200
}

Di tutte queste informazioni, a noi basta estrarre il valore della chiave description e concatenarlo al
nome della citt.

La chiamata nellObserver
Utilizzeremo lObservable della puntata precedente, quello generato dalla lista di citt. La prima
implementazione che possiamo pensare di realizzare quella in cui scriviamo tutta la logica della
chiamata REST nel metodo subscribe e quindi nellObserver.
01 Observable<String>allCities=Observable.just("Zurich","London","Paris",
"Berlin","Roma","Madrid","Wien");
02
03 allCities.subscribe(cityName>{
04 Stringurl=BASE_URL+cityName;
05
06 Clientclient=Client.create();
07 WebResourcewebResource=client.resource(url);
08
09 ClientResponseresponse=
10 webResource.accept("application/json").get(ClientResponse.class);
11
12 if(response.getStatus()!=Status.OK.getStatusCode()){
13 thrownewRuntimeException("Failed:HTTPerrorcode:"+
response.getStatus());
14 }
15
16 Stringoutput=response.getEntity(String.class);
17
18 JsonElementjson=newJsonParser().parse(output);
19
20 Stringweather=json.getAsJsonObject().get("weather")
21 .getAsJsonArray().get(0)
22 .getAsJsonObject().get("description")
23 .getAsString();
24
25 System.out.println(cityName+">"+weather);
26 });
Senza voler entrare troppo nel merito di Jersey, anche se quanto scritto abbastanza semplice, ci basta
sapere che dalla riga 4 alla 15 gestiamo linvocazione del metodo GET sul protocollo HTTP. Dalla riga 18
usiamo Gson, invece, per fare il parsing della risposta: stiamo attraversando lalbero degli elementi per
arrivare ad estrarre la stringa associata alla chiave description. Lultima riga banalmente stampa in
console il risultato. Il tutto infilato dentro unespressione lambda di Java 8 che permette di gestire il
caso onNext dellObservable. Per rendere lesempio pi compatto non stiamo definendo un Observer
intero ma solo cosa fare quando lObservable emette un elemento; stiamo tralasciando il caso di
terminazione e il caso di errore.
http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

4/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

Il risultato dellesecuzione il seguente.


1
2
3
4
5
6
7

Zurich>overcastclouds
London>proximityshowerrain
Paris>mist
Berlin>brokenclouds
Roma>scatteredclouds
Madrid>SkyisClear
Wien>veryheavyrain

La chiamata nellObservable
In effetti potremmo anche accontentarci della soluzione che abbiamo se non ci interessasse gestire in
maniera pi trasparente gli errori, avere una soluzione pi modulare, utilizzare al meglio il
multithreading o capire un po meglio RxJava

. Quindi dimentichiamo in fretta quanto abbiamo scritto

fino qui e costruiamo un Observable che dato un nome di citt ci restituisca il suo meteo attuale
attraverso il servizio REST. Useremo poi questo nuovo oggetto allinterno dellObservable allCities per
ottenere lo stesso risultato.
In effetti RxJava ci permette di creare un Observable utilizzando praticamente qualsiasi cosa. Oltre ad
alcuni metodi come just, otteniamo il massimo della flessibilit usando Observable.create. Questo
metodo prende come parametro un oggetto che implementa linterfaccia Observable.OnSubscribe.
Come fatto questo OnSubscribe? E un alias per linterfaccia Action1<Subscriber<?superT>>.
Cos invece Subscriber? E una classe astratta che implementa Observer.
Ci si pu perdere un po in questo giro, e in effetti chi scrive ha dovuto andare avanti e indietro lungo le
definizioni per venirne fuori. Ma senza badare troppo a tutti i tipi visti, lunica cosa davvero importante
da tenere presente che dobbiamo definire unistanza di OnSubscribe con una lambda e che nel nostro
caso prende in pasto un Subscriber<String> senza restituire niente. A questo Subscriber dobbiamo
passare gli elementi che vogliamo emettere in quanto Observable e terminare, oppure indicare lerrore.
Definita questa funzione la passiamo al metodo Observable.create, fine del lavoro. Vediamolo scritto in
codice.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19

publicstaticObservable<String>getCurrentWeather(finalStringcityName){

Observable.OnSubscribe<String>onSubscribe=subscriber>{

try{
Stringurl=BASE_URL+cityName;

Clientclient=Client.create();
WebResourcewebResource=client.resource(url);

ClientResponseresponse=
webResource.accept("application/json").get(ClientResponse.class);

if(response.getStatus()!=Status.OK.getStatusCode()){
thrownewRuntimeException("Failed:HTTPerrorcode:"+
response.getStatus());
}

Stringoutput=response.getEntity(String.class);

JsonElementjson=newJsonParser().parse(output);

20
http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

5/11

11/11/2015

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

RxJava:trasformareunachiamataRESTinunObservable

Stringweather=json.getAsJsonObject().get("weather")
.getAsJsonArray().get(0)
.getAsJsonObject().get("description")
.getAsString();

subscriber.onNext(weather);
subscriber.onCompleted();
}catch(Exceptione){
subscriber.onError(e);
}
};

returnObservable.create(onSubscribe);
}

Commentiamo un po quanto scritto. Il nostro metodo composto da due istruzioni: nella prima
creiamo la lambda onSubscribe, nella seconda, a riga 33, creiamo lObservable usando la lambda
stessa. Esaminiamo pi in dettaglio la costruzione di onSubscribe: quello che si nota a colpo docchio
che in pratica abbiamo traslocato il codice scritto in precedenza, introducendo per le tre chiamate
canoniche al nostro subscriber. Infatti, dopo aver ottenuto la stringa che ci interessa dal nostro
servizio REST, chiamiamo subscriber.onNext seguito subito da subscriber.onCompleted. In caso di
qualsiasi eccezione invocheremo subscriber.onError.
Per testare che lObservable creato funzioni, ci baster istanziarne uno e sottoscriverlo come in questo
esempio
1 getCurrentWeather("London").subscribe(System.out::println);
Torniamo al problema di partenza, abbiamo la lista di citt, abbiamo lObservable che incapsula la
chiamata REST, come mettiamo assieme i pezzi? Semplicemente con questo codice:
1 Observable<String>allWeathers=allCities.flatMap(city>
getCurrentWeather(city));
2 allWeathers.subscribe(System.out::println);
Loperatore che usiamo non map ma flatMap, infatti se usassimo map otterremmo un
Observable<Observable<String>>, ma cos avremmo un livello di inscatolamento in pi che non ci
serve. Flatmap effettua lo spacchettamento per noi in modo da ritornare un Observable<String>. Il
risultato ottenuto il seguente:
1
2
3
4
5
6
7

overcastclouds
proximityshowerrain
mist
brokenclouds
scatteredclouds
SkyisClear
veryheavyrain

Quanto vediamo pare funzionare ma non abbiamo il nome della citt. Per sistemare le cose, una
soluzione veloce fondere lObservable delle citt con quello del meteo tramite il metodo zip che
abbiamo gi incontrato. Come una cerniera, unisce a coppie gli elementi di due Observable usando una
funzione che decide come combinarli.
1 Observable.zip(allCities,
2 allWeathers,
3 (city,weather)>city+">"+weather)
http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

6/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable
2 allWeathers,
3 (city,weather)>city+">"+weather)
4 .subscribe(System.out::println);

Come successo allinizio del post, la soluzione pi intuitiva non si rivelata la migliore

. Possiamo

ottenere lo stesso risultato con questo codice:


1 allCities.flatMap(city>getCurrentWeather(city).map(weather>city+">"
+weather))
2 .subscribe(System.out::println);
Bisogna guardarlo con attenzione per capire come funziona: abbiamo messo loperatore map allinterno
della chiamata a flatmap, in questo modo abbiamo due lambda, una pi esterna che ha come
parametro city e una pi interna che ha come parametro weather, ma che vede anche la citt nel suo
scope. In questo modo possibile combinarle assieme e risolvere il problema.

Cosa viene dopo


In questo post abbiamo visto come costruire un Observable che incapsuli una chiamata REST. Lidea
usata si pu applicare a qualsiasi tipo di attivit, purch lObservable chiami correttamente i tre metodi
dellObserver. Un esempio interessante quello di costruire un Observable di tweet incapsulando la
classe StatusAdapter di Twitter4J.
Nella prossima parte faremo lavorare gli Observable su thread diversi e vedremo come RxJava ci
semplifichi la vita in questo senso. Torneremo anche a vedere la nostra API meteo in azione facendo
chiamate su servizi diversi e combinandoli assieme. Come per la volta precedente, trovate il codice
utilizzato su GitHub
Related posts:
1. RxJava Observable e Observer RxJava una tecnologia molto interessante che promette di liberarci...
2. Creare un back-end REST con Spark In questo piccolo tutorial analizzeremo Spark: micro-framework per
creare servizi...

3. JUnit Test the REST! Ormai sviluppare servizi web secondo l'architettura REST sembra una moda....

Posted byGiampaolo Trapasso


09/12/2014
4
1
Share:

Google+

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

0
7/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

Related Articles
Retrolambda: lambda expression anche su Java 7
Java 8: uno sguardo agli stream
Primi passi con JBoss 7: nuovi progetti alle prese con il ClassLoader

Liferay: Esporre Web Services Custom

RxJava gestire i thread


Creare un back-end REST con Spark

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

8/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

0Commenti

CoseNonJaviste

Condividi

Consiglia

Entra

Ordinadalmigliore

Inizialadiscussione...

Commentaperprimo.

CHECOS'QUESTO?

ANCHESUCOSENONJAVISTE

AngularJSminiHowTo(primaparte)
2commentiunannofa

GiampaoloTrapassoCiaoFabio,grazie

JSONWebToken:JAASstateless
authenticationperTomcat
2commenti8mesifa

dellasegnalazione.Ieriseraabbiamo
aggiornatoipluginequalcosadeveessere
andatostorto.Orailpost

CoseNonJavisteGrazieAntonio)ho

scopertojwtpercasoperchavevo
bisognopropriodiqueltipodi
autenticazioneperunprogetto.Speroche

AutenticazionediserviziRESTcon
SpringSecurity

LivescreencastsuIonic:marted9
Giugnoore22

3commentiunannofa

2commenti5mesifa

AlessandroNizzoOttimoarticolo.

FrancescoStrazzulloPerfetto!Amarted

Quandosicercaditrasferireunconcetto
comealsolitol'esemplificazionedei
meccanismidibaserisulta

quindi!

Iscriviti

AggiungiDisqusaltuositoweb

Privacy

Ti piace CNJ?
Trovi altri blog di sviluppatori italiani su BlogZinga!

Leggi anche..

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

9/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

Leggi anche..
Dal Waterfall ai Principi Agili
Java 8: lambda in 7 minuti (o quasi)
Primi passi con Spring Batch
Java 8: gli stream infiniti
RxJava Observable e Observer

Libri consigliati

WorkingEffectivelywith
UnitTests...
JayFields,Michae...
Prezzo:

GrowingObjectOriented
Software,Gu...
SteveFreeman,Nat...
Prezzo:EUR54,03

Privacy

Privacy

Mostra altri libri...

I tweet di CNJ

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

10/11

11/11/2015

RxJava:trasformareunachiamataRESTinunObservable

Tweets

Follow

CoseNonJaviste @cosenonjaviste
#CNJHistory Reactnative cosenonjaviste.it/?p=12982

6 Nov

Show Summary

CoseNonJaviste @cosenonjaviste
4 Nov
#CNJHistory Screencast Intro a Scala cosenonjaviste.it/?p=13061
Show Summary

CoseNonJaviste @cosenonjaviste
3 Nov
We are #djangogirlsrome media partner! We'll cover all the event
updates. To learn more follow the official twitter account
@djangogirlsrome
Expand

CoseNonJaviste @cosenonjaviste
#CNJHistory I miei primi passi con Node.js ed Express.js
cosenonjaviste.it/?p=12936

30 Oct

Tweet to @cosenonjaviste

CNJ su Facebook

CoseNonJaviste
684likes

LikePage

ContactUs

1friendlikesthis

[2014] CoseNonJaviste All rights reserved.

http://cosenonjaviste.it/rxjavatrasformareunachiamatarestinunobservable/

11/11

Potrebbero piacerti anche