Ohjelmointi

REST Java-kehittäjille, Osa 2: Restlet väsyneille

Avoimen lähdekoodin Restlet-sovellusliittymä vähentää Java-RESTful-sovellusliittymien rakentamiseen ja kulutukseen liittyvää työmäärää. Tässä toisessa artikkelissa REST Java-kehittäjille -sarjassa Brian Sletten esittelee sinut Restlet-sovellukseen ja käy läpi esimerkkisovelluksen siirtäen käyttöliittymänsä tänään käyttämiisi servlet-kontteihin samalla kun valmistaudutaan tulevaisuuden järjestelmiin. Brian esittelee myös lyhyesti JSR 311: JAX-RS: n, Sunin pyrkimykset integroida RESTful-sovellusliittymät Java EE -pinoon.

Java-kehittäjät ovat olleet pitkään kiinnostuneita REST-arkkitehtuurista, mutta harvat ovat vielä kulkeneet etäisyyden tutun esineiden ja RESTful-resurssien maailman välillä. Vaikka voimme pitää siitä, että muut kielet voivat tuottaa tai kuluttaa RESTful-palveluja, vihaamme tietojen muuntamista tavuvirroiksi ja niistä. Vihaan, että meidän on ajateltava HTTP: tä käytettäessä Apache HTTP Client -sovelluksen kaltaisia ​​työkaluja. Katsomme kaipaavasti wsdl2java -komento, jonka avulla voimme siirtää argumentit SOAP-palveluun yhtä helposti kuin mikä tahansa muu menetelmäpuhelu, pyyhkäisemällä etäpalvelun kutsumisen yksityiskohdat maton alle. Ja havaitsemme, että servlet-malli on hieman liian irti tuotetuista resursseista. Riittää, kun sanon sen, kun olemme olleet pystyy RESTful-palvelujen rakentaminen tyhjästä, se ei ole ollut miellyttävä kokemus.

REST Java-kehittäjille

Lue sarja:

  • Osa 1: Kyse on tiedoista
  • Osa 2: Palautus väsyneille
  • Osa 3: NetKernel

Poliittiset kysymykset ovat joskus lisänneet teknisiä esteitä. Monet johtajat kokevat, että SOAP-pohjaiset verkkopalvelut ovat määrätty tapa rakentaa palvelukeskeisiä arkkitehtuureja Java EE: ssä. Tämä muuttuu tärkeiden toimintojen, kuten JSR 311, JAX-RS: Java-sovellusliittymä RESTful-verkkopalveluille, kanssa, joista opit tässä artikkelissa. Ellei muuta, tämä pyrkimys oikeuttaa RESTful-kehityksen JEE-tilassa.

Samaan aikaan apua on saapunut. Tyylikkäästi avoimen lähdekoodin Restlet-kehyksen avulla on helppo välttää vaikeita ongelmia, joita voi syntyä perinteisen JEE-tekniikan käytöstä RESTful-palvelujen rakentamiseen ja kulutukseen.

Restletin juuret

Ranskalainen ohjelmistokonsultti Jérome Louvel yritti ratkaista joitain teknisiä kysymyksiä, jotka liittyvät RESTin tekemiseen Javan kanssa, luoda kehys, joka tarjoaisi luonnollisemman sovituksen. Hän katsoi ensin NetKernel-ympäristöä lähtökohtana. Niin paljon kuin hän piti siitä, se ei sopinut täydellisesti API-keskittyvään kehykseen, jonka hän pyrki tarjoamaan saataville. Kokemus auttoi vaikuttamaan hänen ajatteluunsa sellaisista asioista, joita REST-suuntautunut ympäristö voi kuitenkin tarjota. (Tämän sarjan seuraava artikkeli tutkii NetKerneliä tarkemmin.)

Kun Louvel työskenteli puitteidensa parissa, hän kehitti kolme tavoitetta:

  • Yksinkertaisten toimintojen tulisi olla yksinkertaisia ​​peruskäytössä. Oletusten pitäisi toimia pienellä vaivalla, mutta niiden on sallittava myös monimutkaisemmat määritykset.
  • Tähän sovellusliittymään kirjoitetun koodin tulisi olla kannettava eri säiliöissä. Vaikka servlet-pohjaisia ​​järjestelmiä voidaan siirtää konttien, kuten Tomcat, laituri ja IBM WebSphere, välillä, Louvelilla oli mielessä suurempi kuva. Servlet-määritys on sidottu HTTP: hen ja estävään I / O-malliin. Hän halusi, että sovellusliittymä on erotettavissa molemmista ja asennettavissa nykyisin käytössä oleviin kontteihin. Hän halusi myös, että ne olisivat käyttökelpoisia pienellä vaivalla vaihtoehtoisissa ja nousevissa säiliöissä, kuten Grizzly, AsyncWeb ja Simple Framework.
  • Sen ei pitäisi rikastuttaa pelkästään palvelinpuolta RESTful-rajapintojen tuottamisessa Java-ohjelmassa, mutta myös asiakaspuolta. HttpURLConnection luokka ja Apache HTTP Client ovat liian matalan tason integroimiseksi puhtaasti suoraan useimpiin sovelluksiin.

Nämä tavoitteet mielessä hän aloitti Restlet-sovellusliittymän tuottamisen. Muutaman vuoden muutoksen jälkeen sovellusliittymä vakiintui ja yhteisö kasvoi sen ympärillä. Nykyään ydinsovellusliittymällä on elinvoimainen käyttäjäkunta, ja käynnissä on merkittävä toiminta integroinnin tukemiseksi muiden työkalupakettien ja aloitteiden, kuten JAX-RS: n, kanssa. (Louvel on nyt JAX-RS-asiantuntijaryhmässä.)

Restlet-perusteet

Peruspalvelin, jossa on Restlet-sovellusliittymä, ei voisi olla helpompaa, kuten luettelossa 1 on esitetty.

Luettelointi 1. Peruspalvelin, jossa on Restlet

paketti net.bosatsu.restlet.basic; tuo org.restlet.Restlet; tuo org.restlet.Server; tuo org.restlet.data.MediaType; tuo org.restlet.data.Protocol; tuo org.restlet.data.Request; tuo org.restlet.data.Response; public class SimpleServer {public static void main (String [] args) heittää poikkeuksen {Restlet restlet = new Restlet () {@Override public void kahva (Request request, Response response) {response.setEntity ("Hei, Java RESTafarians!", MediaType.TEXT_PLAIN); }}; // Vältä ristiriitoja muiden 8080-kuuntelevien Java-konttien kanssa! uusi palvelin (protokolla.HTTP, 8182, uudelleenkäynnistys) .start (); }}

Tämä sovellus ei tee paljoakaan (paitsi levittää hyvää riemua), mutta se osoittaa kaksi Restletin perusperiaatetta. Ensinnäkin yksinkertaiset asiat ovat yksinkertaisia. Monimutkaisemmat toiminnot ovat varmasti mahdollisia, mutta murehdit niistä vain tarvittaessa. RESTiltä puuttuu kyky valvoa turvallisuutta, rajoituksia, sisältöneuvotteluja tai muita tärkeitä tehtäviä. Ne pysyvät suurelta osin ortogonaalisina toimintoina, selvästi erillään RESTful-sovellusliittymän täyttämisprosessista. Kerrostat monimutkaisuuden tarpeen mukaan.

Toiseksi, luettelon 1 koodi on suunniteltu kannettavaksi konttityyppien joukossa. Huomaa, että se ei määritä säilöä. Restlets ovat todellisia resursseja, jotka lopulta vastaavat pyyntöihin. Pyyntöä käsittelevän kontin ja tietoresurssivastaajan välillä ei ole eroa, kuten servlet-mallissa voi olla. Jos kirjoitat koodin IDE: hen ja lisäät riippuvuuksia org.restlet.jar ja com.noelios.restlet.jar arkistoissa, voit suorittaa sovelluksen ja sinun pitäisi nähdä tällainen lokiviesti:

7. joulukuuta 2008 23:37:32 com.noelios.restlet.httpStreamServerHelper start INFO: Sisäisen HTTP-palvelimen käynnistäminen

Osoita selain kohtaan // paikallinen isäntä: 8182, ja sinun pitäisi nähdä ystävällinen tervehdys.

Kulissien takana org.restlet.jar sisältää kaikki tämän API: n tärkeimmät rajapinnat. com.noelios.restlet.jar sisältää näiden liitäntöjen perustoteutuksen ja tarjoaa oletusarvoisen HTTP-käsittelyominaisuuden. Et halua mennä tuotantoon tällä HTTP-moottorilla, mutta se on poikkeuksellisen kätevä kehitys- ja testaustarkoituksiin. Sinun ei tarvitse käynnistää suurta säilöä RESTful-koodisi testaamiseksi. Yksikkö- ja integraatiotestaus voi olla paljon helpompaa.

Luettelon 1 esimerkki käyttää paljon oletuskäyttäytymistä oletusarvon luomiseen Sovellus (keskustelen Sovellus seuraavassa esimerkissä) ja kuuntele HTTP-protokollapyyntöjä portissa 8182. StreamServerHelper luokka alkaa kuunnella tätä porttia ja lähettää pyynnöt Restlet esimerkiksi kun he tulevat sisään.

Louvelin tavoite tukea asiakaspuolen RESTful Java -palvelua saavutetaan myös helposti, kuten näet Listing 2: sta.

Listaus 2. Restlet-asiakas

paketti net.bosatsu.restlet.basic; tuo java.io.IOException; tuo org.restlet.Client; tuo org.restlet.data.Protocol; public class SimpleClient {public static void main (String [] args) heittää IOException {String uri = (args.pituus> 0)? args [0]: "// paikallinen isäntä: 8182"; Asiakasasiakas = uusi asiakas (protokolla.HTTP); client.get (uri) .getEntity (). write (System.out); }}

Kanssa SimpleServer edelleen käynnissä, käynnistämällä tämä uusi asiakaskoodi samoilla JAR-riippuvuuksilla pitäisi tulostaa ystävällinen tervehdys konsolille. Tuloksen tulostaminen tällä tyylillä ei tietenkään toimi binäärisuuntautuneille MIME-tyypeille, mutta se on jälleen kätevä lähtökohta.

Ei-CRUD-esimerkki

Useimmat pedagogiset REST-esimerkit osoittavat CRUDish-palvelut (Luo, Nouda, Päivitä, Poista) yksinkertaisten objektien ympärillä. Vaikka tämä tyyli toimii varmasti hyvin RESTin kanssa, se ei ole suinkaan ainoa järkevä lähestymistapa - ja useimmat meistä ovat kyllästyneet raakoihin esimerkkeihin. Seuraava esimerkki osoittaa Restlet-sovelluksen perusteet käärimällä avoimen lähdekoodin Jazzy-oikeinkirjoituksen tarkistuksen.

REST tarkoittaa tietojen hallintaa, ei mielivaltaisen käyttäytymisen kutsumista, joten sinun on oltava varovainen harkitessasi käyttäytymiskeskeistä sovellusliittymää, kuten Jazzy. Temppu on käsitellä RESTful-sovellusliittymää tietotilana sanoille, joita esiintyy ja joita ei ole olemassa olevissa sanakirjoissa. Ongelma voitaisiin ratkaista monin tavoin, mutta tässä artikkelissa määritellään kaksi tietotilaa. /sanakirja käytetään sanojen hallintaan sanakirjassa. / oikeinkirjoituksen tarkistus käytetään etsimään ehdotuksia väärin kirjoitettuja sanoja muistuttaville sanoille. Molemmat keskittyvät tietoon ottamalla huomioon sanojen puuttumisen tai läsnäolon tietotiloissa.

RESTful-arkkitehtuurissa tämä HTTP-komento voi palauttaa sanan määritelmän sanakirjassa:

GET // paikallinen isäntä: 8182 / sanakirja /sana

Se todennäköisesti palauttaisi HTTP-vastauskoodin "Ei löydy" sanoille, joita ei ole sanakirjassa. Tässä informaatiotilassa on hienoa osoittaa, että sanoja ei ole. Jazzy ei tarjoa sanamääritelmiä, joten jätän sisällön palauttamisen harjoitukseksi lukijalle.

Tämän seuraavan HTTP-komennon tulisi lisätä sana sanakirjaan:

PUT // paikallinen isäntä: 8182 / sanakirja /sana

Tässä esimerkissä käytetään LAITTAA koska voit selvittää mikä URI on /sanakirja tietotilan tulisi olla etukäteen ja antaa useita LAITTAANiiden ei pitäisi tehdä eroa. (LAITTAA on idempotentti pyyntö, kuten SAADA. Saman komennon antaminen useita kertoja ei saisi vaikuttaa.) Jos haluat lisätä määritelmiä, voit siirtää ne runkoina LAITTAA käsittelijä. Jos haluat hyväksyä useita määritelmiä ajan myötä, saatat haluta LÄHETTÄÄ nämä määritelmät, koska LAITTAA on päällekirjoitusoperaatio.

Älä unohda synkronointia

Tässä artikkelissa ei kiinnitetä erityistä huomiota synkronointikysymyksiin, jotta esimerkit pysyisivät kohdennetuina. Älä kohtele tuotantokoodiasi niin epäluuloisesti! Ota yhteyttä esimerkiksi resurssiin Java-samanaikaisuus käytännössä Lisätietoja.

Restlet Luomani tapaukset on sidottava asianmukaisiin tietotiloihin, kuten luettelossa 3 on esitetty.

Listaus 3. Yksinkertainen RESTful-oikeinkirjoituksen tarkistus

paketti net.bosatsu.restlet.spell; tuo com.swabunga.spell.event.SpellChecker; tuo com.swabunga.spell.engine.GenericSpellDictionary; tuo com.swabunga.spell.engine.SpellDictionary; tuo java.io.File; tuo java.io.FileNotFoundException; tuo java.io.IOException; tuo org.restlet.data.Protocol; tuo organisaation pysäytys. *; public class SpellCheckingServer laajentaa sovellusta {public static String dictionary = "Restlet / dict / english.0"; julkinen staattinen SpellDictionary spellingDict; julkinen staattinen SpellChecker spellChecker; julkinen staattinen Restlet-loitsuCheckerRestlet; julkinen staattinen Restlet-sanakirjaRestlet; staattinen {kokeile {spellingDict = uusi GenericSpellDictionary (uusi tiedosto (sanakirja)); spellChecker = uusi SpellChecker (spellingDict); spellCheckerRestlet = uusi SpellCheckerRestlet (spellChecker); dictionaryRestlet = uusi DictionaryRestlet (spellChecker); } catch (Poikkeus e) {e.printStackTrace (); }} public static void main (String [] argumentit) heittää poikkeuksen {Component component = new Component (); component.getServers (). add (Protokolla.HTTP, 8182); SpellCheckingServer spellingService = uusi SpellCheckingServer (); component.getDefaultHost (). attach ("", spellingService); komponentti.aloitus (); } public Restlet createRoot () {Reitittimen reititin = uusi reititin (getContext ()); router.attach ("/ spellchecker / {word}", spellCheckerRestlet); router.attach ("/ sanakirja / {sana}", dictionaryRestlet); palata reititin; }}

Kun se on rakentanut sanakirjainstanssin ja oikeinkirjoituksen tarkistuksen, Listlet 3: n Restlet-asennus on hieman monimutkaisempi kuin edellisessä perusesimerkissä (mutta ei paljon!) Oikeinkirjoituksen tarkistuspalvelin on Restlet-esimerkki Sovellus. An Sovellus on organisaatioluokka, joka koordinoi toiminnallisesti kytkettyjen käyttöönottoa Restlet tapauksia. Ympäröivä Komponentti kysyy Sovellus sen juuresta Restlet soittamalla createRoot () menetelmä. Juuri Restlet palautettu osoittaa, kenen pitäisi vastata ulkoisiin pyyntöihin. Tässä esimerkissä luokka nimeltä Reititin käytetään lähettämään alaisten tietotiloihin. Tämän kontekstisidonnan lisäksi se asettaa URL-osoitemallin, jonka avulla URL-osoitteen "sana" -osa voi olla käytettävissä pyynnössä määritteenä. Tätä hyödynnetään RestletLuodut luetteloissa 4 ja 5.

DictionaryRestlet, joka näkyy luettelossa 4, on vastuussa /sanakirja tietotila.

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