Jar 5 WebClient

1. Prehľad

V tomto výučbe preskúmame Webový klient, čo je reaktívny webový klient predstavený na jar 5.

Taktiež sa pozrieme na WebTestClient, a Webový klient určené na použitie pri testoch.

2. Čo je to Webový klient?

Jednoducho povedané, Webový klient je rozhranie predstavujúce hlavný vstupný bod na vykonávanie webových požiadaviek.

Bol vytvorený ako súčasť modulu Spring Web Reactive a nahradí klasický RestTemplate v týchto scenároch. Nový klient je navyše reaktívnym neblokujúcim riešením, ktoré funguje na protokole HTTP / 1.1.

Napokon má rozhranie jednu implementáciu, DefaultWebClient triedy, s ktorou budeme pracovať.

3. Závislosti

Pretože používame aplikáciu Spring Boot, potrebujeme spring-boot-starter-webflux závislosť, ako aj projekt reaktora.

3.1. Budova s ​​Mavenom

Pridajme nasledujúce závislosti do pom.xml spis:

 org.springframework.boot spring-boot-starter-webflux org.projectreactor reactor-spring 1.0.1.RELEASE 

3.2. Budova s ​​Gradle

S programom Gradle musíme pridať nasledujúce položky do súboru build.gradle spis:

závislosti {compile 'org.springframework.boot: spring-boot-starter-webflux' compile 'org.projectreactor: reactor-spring: 1.0.1.RELEASE'}

4. Práca s Webový klient

Aby sme s klientom fungovali správne, musíme vedieť, ako:

  • vytvoriť inštanciu
  • požiadať
  • vybaviť odpoveď

4.1. Vytvorenie a Webový klient Inštancia

Na výber sú tri možnosti. Prvý z nich je vytvorenie a Webový klient objekt s predvoleným nastavením:

WebClient client1 = WebClient.create (); 

Druhou možnosťou je iniciovať a Webový klient inštancia s daným základným URI:

WebClient client2 = WebClient.create ("// localhost: 8080"); 

Treťou možnosťou (a najpokročilejšou) je vytvorenie klienta pomocou nástroja DefaultWebClientBuilder trieda, ktorá umožňuje úplné prispôsobenie:

WebClient client3 = WebClient .builder () .baseUrl ("// localhost: 8080") .defaultCookie ("cookieKey", "cookieValue") .defaultHeader (HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultUriVariables ("default") "," // localhost: 8080 ")) .build ();

4.2. Vytvorenie a Webový klient Inštancia s časovými limitmi

Predvolené časové limity HTTP 30 sekúnd sú často pre naše potreby príliš pomalé, takže sa pozrime, ako ich nakonfigurovať pre naše potreby. Webový klient inštancia.

Hlavná trieda, ktorú používame, je TcpClient.

Tam môžeme nastaviť časový limit pripojenia cez ChannelOption.CONNECT_TIMEOUT_MILLIS hodnotu. Môžeme tiež nastavte časové limity čítania a zápisu pomocou a ReadTimeoutHandler a a WriteTimeoutHandler, v uvedenom poradí:

TcpClient tcpClient = TcpClient .create () .option (ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) .doOnConnected (pripojenie -> {connection.addHandlerLast (nový ReadTimeoutHandler (5000, TimeUnit.MILLISECONDS)); time.addHandlerLast (odložený) ( MILLISECONDS));}); WebClient client = WebClient.builder () .clientConnector (nový ReactorClientHttpConnector (HttpClient.from (tcpClient))) .build ();

Poznač si to kým môžeme volať čas vypršal aj na našu požiadavku klienta sa jedná o časový limit signálu, nie o pripojenie HTTP, alebo časový limit čítania / zápisu; je to časový limit pre vydavateľa Mono / Flux.

4.3. Príprava žiadosti

Najprv musíme špecifikovať metódu HTTP požiadavky vyvolaním metóda (metóda HttpMethod) alebo volanie jeho skratkových metód ako napr dostať, príspevoka vymazať:

WebClient.UriSpec request1 = client3.method (HttpMethod.POST); WebClient.UriSpec request2 = client3.post ();

Ďalším krokom je zadanie adresy URL. Môžeme to odovzdať uri API ako a String alebo a java.net.URL inštancia:

WebClient.RequestBodySpec uri1 = client3 .method (HttpMethod.POST) .uri ("/ zdroj"); WebClient.RequestBodySpec uri2 = client3 .post () .uri (URI.create ("/ resource"));

Potom môžeme v prípade potreby nastaviť telo žiadosti, typ obsahu, dĺžku, súbory cookie alebo hlavičky.

Napríklad, ak chceme nastaviť telo žiadosti, sú k dispozícii dva spôsoby: vyplnenie a BodyInserter alebo delegovaním tejto práce na a Vydavateľ:

WebClient.RequestHeadersSpec requestSpec1 = WebClient .create () .method (HttpMethod.POST) .uri ("/ resource") .body (BodyInserters.fromPublisher (Mono.just ("data")), String.class); WebClient.RequestHeadersSpec requestSpec2 = WebClient .create ("// localhost: 8080") .post () .uri (URI.create ("/ resource")) .body (BodyInserters.fromObject ("data"));

The BodyInserter je rozhranie zodpovedné za vyplnenie a ReactiveHttpOutputMessage telo s danou výstupnou správou a kontextom použitým počas vkladania. A Vydavateľ je reaktívny komponent, ktorý je zodpovedný za zabezpečenie potenciálne neobmedzeného počtu radených prvkov.

Druhým spôsobom je telo metóda, čo je skratka pre originál telo (vkladač BodyInserter) metóda.

Na uľahčenie procesu plnenia a BodyInserter, existuje BodyInserters trieda s množstvom užitočných úžitkových metód:

BodyInserter insertter1 = BodyInserters .fromPublisher (Subscriber :: onComplete, String.class); 

Je to možné aj s a MultiValueMap:

Mapa LinkedMultiValueMap = nová LinkedMultiValueMap (); map.add ("kľúč1", "hodnota1"); map.add ("key2", "value2"); BodyInserter inserter2 = BodyInserters.fromMultipartData (mapa); 

Alebo pomocou jedného objektu:

BodyInserter inserter3 = BodyInserters.fromObject (nový objekt ()); 

Po nastavení tela môžeme nastaviť hlavičky, súbory cookie a prijateľné typy médií. Hodnoty sa pridajú k tým, ktoré už boli nastavené pri vytváraní inštancie klienta.

K dispozícii je tiež ďalšia podpora pre najčastejšie používané hlavičky, ako sú „If-None-Match“, „If-Modified-since“, „Accept“, a „Accept-Charset“.

Tu je príklad použitia týchto hodnôt:

WebClient.ResponseSpec response1 = uri1 .body (inserter3) .header (HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .accept (MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML).) "*") .ifModifiedSince (ZonedDateTime.now ()) .retrieve ();

4.4. Získanie odpovede

Poslednou fázou je odoslanie žiadosti a prijatie odpovede. Toto je možné vykonať pomocou: výmena alebo načítať metóda.

Tieto metódy sa líšia v návratových typoch; the výmena metóda poskytuje a ClientResponse spolu s jeho stavom a hlavičkami, zatiaľ čo načítať metóda je najkratšia cesta k získaniu tela priamo:

Reťazec response2 = request1.exchange () .block () .bodyToMono (String.class) .block (); Reťazcová odpoveď3 = požiadavka2 .retrieve () .bodyToMono (String.class) .block ();

Je dôležité venovať pozornosť bodyToMono metóda, ktorá vrhne a WebClientException ak je stavový kód 4xx (chyba klienta) príp 5xx (Chyba servera). Používame blokovať metóda na Monos na predplatné a získanie aktuálnych údajov, ktoré boli odoslané s odpoveďou.

5. Práca s WebTestClient

The WebTestClient je hlavným vstupným bodom pre testovanie koncových bodov servera WebFlux. Má veľmi podobné API ako Webový klient, a deleguje väčšinu práce na interných Webový klient inštancia zameraná hlavne na poskytnutie testovacieho kontextu. The DefaultWebTestClient triedy je implementácia jedného rozhrania.

Klient na testovanie môže byť viazaný na skutočný server alebo pracovať s konkrétnymi radičmi alebo funkciami.

5.1. Viazanie na server

Na dokončenie komplexných testov integrácie so skutočnými požiadavkami na spustený server môžeme použiť bindToServer metóda:

WebTestClient testClient = WebTestClient .bindToServer () .baseUrl ("// localhost: 8080") .build (); 

5.2. Viazanie na smerovač

Môžeme otestovať konkrétny údaj Funkcia smerovača odovzdaním do bindToRouterFunction metóda:

RouterFunction function = RouterFunctions.route (RequestPredicates.GET ("/ resource"), request -> ServerResponse.ok (). Build ()); WebTestClient .bindToRouterFunction (funkcia) .build (). Get (). Uri ("/ zdroj") .exchange () .expectStatus (). IsOk () .expectBody (). IsEmpty (); 

5.3. Viazanie na obslužnú rutinu webu

Rovnaké správanie je možné dosiahnuť aj pri bindToWebHandler metóda, ktorá vyžaduje a WebHandler inštancia:

Obslužný program WebHandler = výmena -> Mono.empty (); WebTestClient.bindToWebHandler (obslužný program) .build ();

5.4. Viazanie na kontext aplikácie

Zaujímavejšia situácia nastane, keď používame bindToApplicationContext metóda. Trvá to ApplicationContext a analyzuje kontext pre fazuľu regulátora a @EnableWebFlux konfigurácie.

Ak vložíme inštanciu ApplicationContext, jednoduchý útržok kódu môže vyzerať takto:

@Autowired private ApplicationContext context; WebTestClient testClient = WebTestClient.bindToApplicationContext (kontext) .build (); 

5.5. Viazanie na kontrolóra

Kratší prístup by bol poskytnutie radu ovládačov, ktoré chceme vyskúšať bindToController metóda. Za predpokladu, že máme Kontrolór triedy a vložili sme ju do potrebnej triedy, môžeme napísať:

@Autowired private Controller controller; WebTestClient testClient = WebTestClient.bindToController (radič) .build (); 

5.6. Podanie žiadosti

Po vybudovaní a WebTestClient objekt, všetky nasledujúce operácie v reťazci budú podobné operácii Webový klient až pokým výmena metóda (jeden spôsob ako získať odpoveď), ktorá poskytuje WebTestClient.ResponseSpec rozhranie pre prácu s užitočnými metódami ako expectStatus, expectBodya expectHeader:

WebTestClient .bindToServer () .baseUrl ("// localhost: 8080") .build () .post () .uri ("/ zdroj") .exchange () .expectStatus (). IsCreated () .expectHeader (). ValueEquals („Content-Type“, „application / json“) .expectBody (). IsEmpty (); 

6. Záver

V tomto článku sme preskúmali Webový klient, nový vylepšený pružinový mechanizmus na zadávanie požiadaviek na strane klienta.

Pozreli sme sa tiež na výhody, ktoré poskytuje, tým, že sme prešli konfiguráciou klienta, prípravou žiadosti a spracovaním odpovede.

Všetky útržky kódu uvedené v článku nájdete v našom úložisku GitHub.