Bevezetés a tavaszi távirányításhoz a HTTP-meghívókkal

1. Áttekintés

Bizonyos esetekben egy rendszert több folyamatra kell bontanunk, amelyek mindegyike felelősséget vállal az alkalmazásunk különböző aspektusaiért. Ilyen esetekben nem ritka, hogy az egyik folyamatnak szinkron módon kell adatokat szereznie egy másiktól.

A tavaszi keretrendszer számos eszközt kínál átfogóan Tavaszi távirányítás ez lehetővé teszi számunkra a távoli szolgáltatások igénybevételét, mintha azok legalább bizonyos mértékben helyben elérhetőek lennének.

Ebben a cikkben egy alkalmazást állítunk fel a Spring's alapján HTTP invoker, amely kihasználja a natív Java-sorosítást és a HTTP-t, hogy távoli módszerhívást biztosítson az ügyfél és a kiszolgálóalkalmazás között.

2. Szolgáltatás meghatározása

Tegyük fel, hogy olyan rendszert kell bevezetnünk, amely lehetővé teszi a felhasználók számára, hogy utast foglaljanak egy fülkében.

Tegyük fel azt is, hogy az építést választjuk két különálló alkalmazás e cél elérése érdekében:

  • - egy foglaló motor alkalmazás annak ellenőrzésére, hogy a fülke kérés teljesíthető-e, és
  • egy olyan elülső webalkalmazás, amely lehetővé teszi az ügyfelek számára, hogy lefoglalják túráikat, biztosítva a fülke rendelkezésre állását

2.1. Szolgáltatási felület

Amikor használjuk Tavaszi távirányítás val vel HTTP invoker, meg kell határoznunk a távolról hívható szolgáltatásunkat egy interfészen keresztül, hogy a Spring mind kliens, mind szerver oldalon olyan proxyképeket hozzon létre, amelyek a távoli hívás technikáit foglalják magukba. Kezdjük tehát egy olyan szolgáltatás felületével, amely lehetővé teszi számunkra a fülke foglalását:

nyilvános felület CabBookingService {Booking bookRide (String pickUpLocation) dobja a BookingException-t; }

Amikor a szolgáltatás képes kiosztani egy taxit, akkor a-t ad vissza Foglalás objektum foglalási kóddal. Foglalás sorosíthatónak kell lennie, mert a Spring HTTP-meghívójának át kell töltenie példányait a szerverről az ügyfélre:

public class foglalás a Serializable {private String bookingCode; @Orride public String toString () {return formátum ("Megerősített utazás: kód: '% s'.", BookingCode); } // szokásos mérőeszközök / beállítók és konstruktor}

Ha a szolgáltatás nem képes taxit foglalni, a BookingException dobják. Ebben az esetben nem szükséges az osztályt jelölni Sorosítható mivel Kivétel már megvalósítja:

public class BookingException kiterjeszti a Exception {public BookingException (String üzenet) {super (message); }}

2.2. A Szolgáltatás csomagolása

A szolgáltatási felületnek, az összes argumentumként használt osztálynak, a visszatérési típusoknak és a kivételeknek mind az ügyfél, mind a kiszolgáló osztályútvonalán elérhetőnek kell lenniük. Ennek egyik leghatékonyabb módja, ha mindet a .befőttes üveg fájl, amely később függőségként felvehető a szerver és az ügyfél fájljába pom.xml.

Helyezzük így az összes kódot egy dedikált Maven modulba, az úgynevezett „api” -ba; erre a példára a következő Maven-koordinátákat használjuk:

com.baeldung api 1.0-SNAPSHOT

3. Kiszolgáló alkalmazás

Készítsük el a foglaló motor alkalmazást, hogy lássuk a szolgáltatást a Spring Boot segítségével.

3.1. Maven-függőségek

Először meg kell győződnie arról, hogy a projekt a Tavaszi indítást használja:

 org.springframework.boot spring-boot-starter-parent 2.2.2.KÖZLEMÉNY 

Az utolsó Spring Boot verziót itt találja. Ezután szükségünk van a webes indító modulra:

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

És szükségünk van az előző lépésben összeállított szolgáltatásdefiníciós modulra:

 com.baeldung api 1.0-SNAPSHOT 

3.2. Szolgáltatás megvalósítása

Először meghatározunk egy osztályt, amely megvalósítja a szolgáltatás felületét:

public class CabBookingServiceImpl megvalósítja a CabBookingService {@Override public Booking bookPickUp (String pickUpLocation) dobja a BookingException {if (random () <0,3) új BookingException-t ("A fülke nem elérhető"); visszatér az új foglaláshoz (randomUUID (). toString ()); }}

Tegyünk úgy, mintha ez valószínű megvalósítás lenne. Véletlenszerű értékű teszt használatával képesek leszünk reprodukálni mind a sikeres forgatókönyveket - amikor egy szabad fülke megtalálható és foglalási kódot adunk vissza -, mind a sikertelen forgatókönyveket - amikor egy BookingException dobódik, jelezve, hogy nincs szabad fülke.

3.3. A szolgáltatás feltárása

Ezután meg kell határoznunk egy alkalmazást egy típusú babgal HttpInvokerServiceExporter a kontextusban. Gondoskodik egy HTTP belépési pont kitettségéről a webalkalmazásban, amelyet később az ügyfél meghív:

@Configuration @ComponentScan @EnableAutoConfiguration public class Server {@Bean (name = "/ booking") HttpInvokerServiceExporter accountService () {HttpInvokerServiceExporter exportorter = new HttpInvokerServiceExporter (); exportőr.setService (új CabBookingServiceImpl ()); exportőr.setServiceInterface (CabBookingService.class); visszatérő exportőr; } public static void main (String [] args) {SpringApplication.run (Server.class, args); }}

Érdemes megjegyezni, hogy a tavaszi HTTP invoker a. nevét használja HttpInvokerServiceExporter bab, mint a HTTP végpont URL relatív elérési útja.

Most már elindíthatjuk a szerveralkalmazást, és folyamatosan futtathatjuk, amíg beállítjuk az ügyfélalkalmazást.

4. Kliens alkalmazás

Most írjuk meg az ügyfélalkalmazást.

4.1. Maven-függőségek

Ugyanazt a szolgáltatásdefiníciót és ugyanazt a Spring Boot verziót fogjuk használni, amelyet a szerver oldalon használtunk. Még mindig szükségünk van a webindító függőségére, de mivel nem kell automatikusan elindítanunk egy beágyazott tárolót, kizárhatjuk a Tomcat indítót a függőségből:

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

4.2. Ügyfélmegvalósítás

Vezessük be az ügyfelet:

@Configuration public class Client {@Bean public HttpInvokerProxyFactoryBean invoker () {HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean (); invoker.setServiceUrl ("// localhost: 8080 / booking"); invoker.setServiceInterface (CabBookingService.class); visszahívó; } public static void main (String [] args) dobja a BookingException {CabBookingService service = SpringApplication .run (Client.class, args) .getBean (CabBookingService.class); out.println (service.bookRide ("13 Seagate Blvd, Key Largo, FL 33037")); }}

A @Bab annotált invoker() metódus létrehozza a HttpInvokerProxyFactoryBean. Meg kell adnunk azt az URL-t, amelyre a távoli szerver válaszol setServiceUrl () módszer.

Hasonlóképpen, mint amit a szerver érdekében tettünk, meg kell adnunk annak a szolgáltatásnak az interfészét is, amelyet távolról meg akarunk hívni. setServiceInterface () módszer.

HttpInvokerProxyFactoryBean megvalósítja a tavaszit FactoryBean. A FactoryBean babként definiálva van, de a Spring IoC konténer az általa létrehozott objektumot fogja injektálni, nem magát a gyárat. További részletek a következőkről: FactoryBean gyári bab cikkünkben.

A fő() metódus elindítja az önálló alkalmazást és megszerzi a CabBookingService a kontextusból. A motorháztető alatt ez az objektum csak egy proxy, amelyet a HttpInvokerProxyFactoryBean amely gondoskodik a távoli meghívás végrehajtásában részt vevő összes technikáról. Ennek köszönhetően most már könnyedén használhatjuk a proxyt, akárcsak akkor, ha a szolgáltatás megvalósítása helyben elérhető lett volna.

Futtassuk az alkalmazást többször több távoli hívás végrehajtására annak ellenőrzésére, hogy az ügyfél hogyan viselkedik, amikor a fülke rendelkezésre áll, és amikor nem.

5. Caveat Emptor

Amikor olyan technológiákkal dolgozunk, amelyek lehetővé teszik a távoli invokációt, vannak olyan buktatók, amelyekkel jól tisztában kell lennünk.

5.1. Vigyázzon a hálózattal kapcsolatos kivételekkel

Mindig számítanunk kell a váratlanokra, ha megbízhatatlan erőforrással dolgozunk, mint hálózat.

Tegyük fel, hogy az ügyfél akkor hívja a szervert, amikor az nem érhető el - sem hálózati probléma miatt, sem azért, mert a szerver nem működik -, akkor a Tavaszi távvezérlés RemoteAccessException az egy RuntimeException.

A fordító ekkor nem kényszerít minket arra, hogy az invokációt belefoglaljuk egy try-catch blokkba, de mindig meg kell fontolnunk, hogy megtesszük-e, hogy megfelelően kezeljük-e a hálózati problémákat.

5.2. Az objektumokat érték, nem referencia alapján továbbítják

Tavaszi távoli HTTP marsallok metódusának argumentumai és visszaadott értékei, hogy továbbítsák őket a hálózaton. Ez azt jelenti, hogy a szerver a megadott argumentum másolatára, az ügyfél pedig a szerver által létrehozott eredmény másolatára hat.

Tehát nem számíthatunk például arra, hogy egy metódus meghívása az eredményül kapott objektumra megváltoztatja ugyanazon objektum állapotát a kiszolgáló oldalon, mert az ügyfél és a kiszolgáló között nincs megosztott objektum.

5.3. Óvakodjon a finomszemcsés interfészektől

A módszer meghívása a hálózati határokon túl lényegesen lassabb, mint egy objektumra ugyanabban a folyamatban.

Emiatt általában jó gyakorlat olyan szolgáltatásokat meghatározni, amelyeket távolabbról kell meghívni durvább szemcsés interfészekkel, amelyek képesek kevesebb interakciót igénylő üzleti tranzakciók befejezésére, még a nehezebb felület rovására is.

6. Következtetés

Ezzel a példával láttuk, hogy a Tavaszi távvezérléssel mennyire egyszerű távoli folyamatot meghívni.

A megoldás kissé kevésbé nyitott, mint más olyan elterjedt mechanizmusok, mint a REST vagy a webszolgáltatások, de olyan esetekben, amikor az összes komponenst Spring-szel fejlesztik, ez életképes és sokkal gyorsabb alternatívát jelenthet.

Szokás szerint a forrásokat a GitHubon találja meg.