Úvod do jarného diaľkového ovládania s vyvolávačmi HTTP

1. Prehľad

V niektorých prípadoch musíme systém rozložiť na niekoľko procesov, pričom každý z nich prevezme zodpovednosť za iný aspekt našej aplikácie. V týchto scenároch nie je nezvyčajné, že jeden z procesov musí synchronne získavať údaje z iného.

Jarný rámec ponúka celý rad nástrojov, ktoré sa komplexne nazývajú Jarná diaľková komunikácia to nám umožňuje vyvolať vzdialené služby, akoby boli aspoň do istej miery dostupné lokálne.

V tomto článku nastavíme aplikáciu založenú na Spring’s Vyvolávač HTTP, ktorý využíva natívnu serializáciu Java a HTTP na zabezpečenie vzdialeného vyvolania metódy medzi klientom a serverovou aplikáciou.

2. Definícia služby

Predpokladajme, že musíme implementovať systém, ktorý používateľom umožní rezervovať si jazdu v kabíne.

Predpokladajme tiež, že sme sa rozhodli stavať dve odlišné aplikácie na dosiahnutie tohto cieľa:

  • - aplikáciu rezervačného nástroja na kontrolu, či je možné vyhovieť požiadavke na taxík, a -
  • front-end webová aplikácia, ktorá zákazníkom umožňuje rezervovať si jazdy, čím sa potvrdzuje dostupnosť kabíny

2.1. Servisné rozhranie

Keď použijeme Jarná diaľková komunikácia s Vyvolávač HTTP, musíme definovať našu diaľkovo volanú službu prostredníctvom rozhrania, aby sme umožnili spoločnosti Spring vytvoriť proxy na strane klienta aj servera, ktoré zapuzdria technické podrobnosti vzdialeného hovoru. Začnime teda rozhraním služby, ktorá nám umožňuje rezervovať taxík:

verejné rozhranie CabBookingService {Booking bookRide (String pickUpLocation) vyvolá BookingException; }

Ak je služba schopná prideliť taxík, vráti a Rezervácia objekt s rezervačným kódom. Rezervácia musí byť serializovateľný, pretože Spring's HTTP invoker musí prenášať svoje inštancie zo servera do klienta:

public class Booking implementuje Serializable {private String bookingCode; @Override public String toString () {návratový formát ("Jazda potvrdená: kód '% s'.", BookingCode); } // štandardné getre / setre a konštruktor}

Ak služba nie je schopná rezervovať taxík, a Výnimka z rezervácie je hodená. V takom prípade nie je potrebné triedu označovať ako Serializovateľné pretože Výnimka už ho implementuje:

public class BookingException rozširuje Exception {public BookingException (String message) {super (message); }}

2.2. Balenie služby

Rozhranie služby spolu so všetkými vlastnými triedami používanými ako argumenty, návratové typy a výnimky musia byť k dispozícii v triede klienta aj servera. Jedným z najefektívnejších spôsobov, ako to urobiť, je zabaliť všetky do a .jar súbor, ktorý je možné neskôr zahrnúť ako závislosť do servera a klienta pom.xml.

Poďme teda vložiť všetok kód do vyhradeného modulu Maven, ktorý sa nazýva „api“; pre tento príklad použijeme nasledujúce súradnice Maven:

com.baeldung api 1,0-SNAPSHOT

3. Serverová aplikácia

Vytvorme aplikáciu rezervačného nástroja na vystavenie služby pomocou Spring Boot.

3.1. Maven závislosti

Najskôr sa musíte ubezpečiť, že váš projekt používa Spring Boot:

 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE 

Poslednú verziu Spring Boot nájdete tu. Potom potrebujeme modul Webový štartér:

 org.springframework.boot spring-boot-starter-web 

Potrebujeme modul definície služby, ktorý sme zostavili v predchádzajúcom kroku:

 com.baeldung api 1,0-SNAPSHOT 

3.2. Implementácia služby

Najskôr definujeme triedu, ktorá implementuje rozhranie služby:

verejná trieda CabBookingServiceImpl implementuje CabBookingService {@Override public Booking bookPickUp (String pickUpLocation) hodí BookingException {if (random () <0,3) hodí novú BookingException ("Cab nie je k dispozícii"); vrátiť novú rezerváciu (randomUUID (). toString ()); }}

Predstierajme, že ide o pravdepodobnú implementáciu. Pomocou testu s náhodnou hodnotou budeme schopní reprodukovať úspešné scenáre - keď sa nájde dostupná kabína a vráti sa rezervačný kód - a zlyhajúce scenáre - keď sa vyvolá výnimka BookingException, ktorá naznačuje, že nie je k dispozícii žiadna kabína.

3.3. Vystavenie Služby

Potom musíme definovať aplikáciu s fazuľou typu HttpInvokerServiceExporter v kontexte. Postará sa o odhalenie vstupného bodu HTTP vo webovej aplikácii, ktorý bude neskôr klientom vyvolaný:

@Configuration @ComponentScan @EnableAutoConfiguration verejná trieda Server {@Bean (name = "/ booking") HttpInvokerServiceExporter accountService () {HttpInvokerServiceExporter exportér = nový HttpInvokerServiceExporter (); exporter.setService (nový CabBookingServiceImpl ()); exporter.setServiceInterface (CabBookingService.class); spätný vývozca; } public static void main (String [] args) {SpringApplication.run (Server.class, args); }}

Stojí za zmienku, že Spring’s Vyvolávač HTTP používa názov HttpInvokerServiceExporter bean ako relatívna cesta k URL koncového bodu HTTP.

Teraz môžeme serverovú aplikáciu spustiť a nechať ju bežať, kým nastavujeme klientsku aplikáciu.

4. Klientská aplikácia

Poďme teraz napísať klientskú aplikáciu.

4.1. Maven závislosti

Použijeme rovnakú definíciu služby a rovnakú verziu Spring Boot, ktorú sme použili na strane servera. Stále potrebujeme závislosť webového štartéra, ale keďže nemusíme automaticky spúšťať vložený kontajner, môžeme vylúčiť štartér Tomcat zo závislosti:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat 

4.2. Implementácia klienta

Implementujme klienta:

@Configuration public class Client {@Bean public HttpInvokerProxyFactoryBean invoker () {HttpInvokerProxyFactoryBean invoker = nový HttpInvokerProxyFactoryBean (); invoker.setServiceUrl ("// localhost: 8080 / booking"); invoker.setServiceInterface (CabBookingService.class); návratový vyvolávač; } public static void main (String [] args) hodí BookingException {služba CabBookingService = SpringApplication .run (Client.class, args) .getBean (CabBookingService.class); out.println (service.bookRide ("13 Seagate Blvd, Key Largo, FL 33037")); }}

The @Bean komentovaný vyvolávač() metóda vytvorí inštanciu HttpInvokerProxyFactoryBean. Musíme zadať adresu URL, na ktorú vzdialený server odpovedá prostredníctvom servera setServiceUrl () metóda.

Podobne ako to, čo sme urobili pre server, by sme mali poskytnúť aj rozhranie služby, ktorú chceme na diaľku vyvolať prostredníctvom servera setServiceInterface () metóda.

HttpInvokerProxyFactoryBean realizuje jar FactoryBean. A FactoryBean je definované ako fazuľa, ale kontajner Spring IoC vstrekne objekt, ktorý vytvorí, nie samotnú továreň. Viac podrobností nájdete na FactoryBean v našom článku o fazuľových výrobkoch.

The hlavný() metóda bootstraps samostatnú aplikáciu a získa inštanciu CabBookingService z kontextu. Pod kapotou je tento objekt iba serverom proxy vytvoreným serverom HttpInvokerProxyFactoryBean ktorá sa stará o všetky technické úkony spojené s vykonávaním vzdialeného vyvolania. Vďaka tomu teraz môžeme ľahko používať proxy server, ako by sme to robili, keby bola implementácia služby dostupná lokálne.

Spustime aplikáciu niekoľkokrát, aby sme vykonali niekoľko vzdialených hovorov, aby sme overili, ako sa chová klient, keď je k dispozícii taxík a kedy nie.

5. Upozornenie Emptor

Keď pracujeme s technológiami, ktoré umožňujú vzdialené vyvolanie, musíme si dobre uvedomiť niektoré úskalia.

5.1. Pozor na výnimky týkajúce sa siete

Keď pracujeme s nespoľahlivým zdrojom ako sieť, mali by sme vždy očakávať neočakávané.

Predpokladajme, že klient vyvoláva server, zatiaľ čo na neho nie je možné dosiahnuť - buď kvôli problémom so sieťou, alebo kvôli výpadku servera - a potom Spring Remoting vyvolá RemoteAccessException toto je RuntimeException.

Kompilátor nás potom nebude nútiť zahrnúť vyvolanie do bloku try-catch, ale mali by sme to vždy zvážiť, aby sme správne zvládli problémy so sieťou.

5.2. Objekty sa prenášajú podľa hodnoty, nie podľa referencie

Jarná vzdialená komunikácia HTTP argumenty metódy marshals a vrátené hodnoty na ich prenos v sieti. To znamená, že server koná na základe kópie poskytnutého argumentu a klient na základe kópie výsledku vytvoreného serverom.

Nemôžeme teda očakávať, že napríklad vyvolanie metódy na výslednom objekte zmení stav toho istého objektu na strane servera, pretože medzi klientom a serverom nie je žiadny zdieľaný objekt.

5.3. Dajte si pozor na jemnozrnné rozhrania

Vyvolanie metódy cez hranice siete je podstatne pomalšie ako jej vyvolanie na objekte v rovnakom procese.

Z tohto dôvodu je zvyčajne dobrým zvykom definovať služby, ktoré by sa mali vzdialene vyvolať pomocou hrubších rozhraní, ktoré sú schopné dokončiť obchodné transakcie vyžadujúce menej interakcií, a to aj na úkor ťažkopádnejšieho rozhrania.

6. Záver

Na tomto príklade sme videli, ako je pri aplikácii Spring Remoting ľahké vyvolať vzdialený proces.

Riešenie je o niečo menej otvorené ako iné rozšírené mechanizmy, ako sú REST alebo webové služby, ale v scenároch, kde sú všetky komponenty vyvíjané s programom Spring, môže predstavovať životaschopnú a oveľa rýchlejšiu alternatívu.

Ako obvykle, zdroje nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found