Open-source Restlet API snižuje pracovní zátěž spojenou s vytvářením a spotřebováváním RESTful API v Javě. V tomto druhém článku v REST pro vývojáře Java Brian Sletten vám představí Restlet a provede ukázkovou aplikaci při nasazování jejích rozhraní do servletových kontejnerů, které používáte dnes, a zároveň se připravuje na systémy budoucnosti. Brian také krátce představuje JSR 311: JAX-RS, snahu společnosti Sun o integraci rozhraní RESTful API do zásobníku Java EE.
Vývojáři prostředí Java se dlouho zajímali o architektonický styl REST, ale jen málo z nich dosud urazilo vzdálenost mezi známým světem objektů a světem RESTful zdrojů. I když se nám může líbit skutečnost, že služby RESTful mohou být vytvářeny nebo spotřebovávány jinými jazyky, nenávidíme nutnost převádět data do a z bajtových proudů. Nesnášíme, když musíme myslet na HTTP, když používáme nástroje jako Apache HTTP Client. Toužebně se díváme na objekty vytvořené wsdl2java
příkaz, který nám umožňuje předávat argumenty do služby SOAP stejně snadno jako jakékoli jiné volání metody, a zametat podrobnosti vyvolání vzdálené služby pod koberec. A zjistíme, že model servletu je jen trochu příliš odpojen od produkovaných zdrojů. Stačí říct, že když jsme byli schopný vybudovat služby RESTful od nuly, nebyl to příjemný zážitek.
REST pro vývojáře Java
Přečtěte si sérii:
- Část 1: Jedná se o informace
- Část 2: Restlet pro unavené
- Část 3: NetKernel
Politické problémy někdy spojovaly technické překážky. Mnoho manažerů má pocit, že webové služby založené na protokolu SOAP jsou předepsaným způsobem vytváření architektur orientovaných na služby (SOA) v prostředí Java EE. To se mění se vznikem důležitých činností, jako jsou JSR 311, JAX-RS: Java API pro RESTful Web Services, o kterých se dozvíte v tomto článku. Pokud nic jiného, toto úsilí legitimuje RESTful vývoj v prostoru JEE.
Mezitím dorazila pomoc. Elegantním způsobem umožňuje otevřený rámec Restletu vyhnout se trnitým problémům, které mohou nastat při používání tradiční technologie JEE k vytváření a využívání služeb RESTful.
Restletovy kořeny
Ve snaze řešit některé technické problémy spojené s prováděním REST s Javou se Jérome Louvel, francouzský softwarový konzultant, snažil vytvořit rámec, který by poskytoval přirozenější střih. Nejprve se podíval na prostředí NetKernel jako na výchozí bod. Jakkoli se mu líbilo, nebylo to perfektní řešení pro rámec zaměřený na API, který se snažil zpřístupnit. Zkušenost však pomohla ovlivnit jeho myšlení o tom, co všechno může prostředí orientované na REST nabídnout. (Následující článek v této sérii prozkoumá NetKernel podrobněji.)
Když Louvel pracoval na svém rámci, vytvořil tři cíle:
- Pro základní použití by měly být jednoduché akce jednoduché. Výchozí hodnoty by měly fungovat s minimálním úsilím, ale také by měly umožňovat složitější konfigurace.
- Kód zapsaný do tohoto API by měl být přenositelný napříč kontejnery. Přestože systémy založené na servletech lze přesouvat mezi kontejnery, jako jsou Tomcat, Jetty a IBM WebSphere, měl Louvel na mysli větší obrázek. Specifikace servletu je vázána na HTTP a blokující I / O model. Chtěl, aby jeho API bylo oddělitelné od obou a nasaditelné do dnes používaných kontejnerů. Také chtěl, aby byly použitelné s malým úsilím v alternativních a vznikajících kontejnerech, jako jsou Grizzly, AsyncWeb a Simple Framework.
- Nemělo by to obohatit pouze serverovou stranu výroby rozhraní RESTful v Javě, ale také klientskou stranu. The
HttpURLConnection
třída a klient Apache HTTP jsou příliš nízké úrovně na to, aby se mohli čistě integrovat přímo do většiny aplikací.
S ohledem na tyto cíle se vydal na produkci Restlet API. Po několika letech vývoje se API stalo stabilním a kolem něj rostla komunita. Dnes má jádro API živou uživatelskou základnu a probíhají významné aktivity na podporu integrace s dalšími nástrojovými sadami a iniciativami, jako je JAX-RS. (Louvel je nyní ve skupině odborníků JAX-RS.)
Základy restletu
Základní server s Restlet API už snad nemůže být jednodušší, jak je uvedeno v seznamu 1.
Výpis 1. Základní server s Restletem
balíček net.bosatsu.restlet.basic; import org.restlet.Restlet; import org.restlet.Server; import org.restlet.data.MediaType; import org.restlet.data.Protocol; import org.restlet.data.Request; importovat org.restlet.data.Response; public class SimpleServer {public static void main (String [] args) throws Exception {Restlet restlet = new Restlet () {@Override public void handle (Request request, Response response) {response.setEntity ("Hello, Java RESTafarians!", MediaType.TEXT_PLAIN); }}; // Vyhněte se konfliktům s jinými kontejnery Java naslouchajícími na 8080! nový server (Protocol.HTTP, 8182, restlet) .start (); }}
Tato aplikace moc nedělá (kromě šíření dobré nálady), ale ukazuje dva základní principy společnosti Restlet. Za prvé, jednoduché věci jsou jednoduché. Složitější činnosti jsou jistě možné, ale staráte se o ně pouze tehdy, když potřebujete. RESTu nechybí schopnost vynucovat zabezpečení, omezení, vyjednávání obsahu nebo jiné důležité úkoly. Ty zůstávají převážně ortogonálními aktivitami, zcela odlišnými od procesu uspokojování RESTful API. Složitost navrstvíte podle potřeby.
Za druhé, kód v seznamu 1 je navržen tak, aby byl přenosný mezi typy kontejnerů. Všimněte si, že neurčuje kontejner. Restlet
s jsou skutečné zdroje, které nakonec reagují na požadavky. Neexistuje žádný rozdíl mezi kontejnerem zpracovávajícím požadavek a respondérem informačních zdrojů, jak může být v modelu servletu. Pokud zadáte kód do IDE a přidáte závislosti na org.restlet.jar
a com.noelios.restlet.jar
archivů, můžete aplikaci spustit a měla by se zobrazit taková zpráva protokolu:
7. prosince 2008 23:37:32 com.noelios.restlet.http.StreamServerHelper start INFO: Spuštění interního serveru HTTP
Nasměrujte prohlížeč na // localhost: 8182
a měli byste vidět přátelský pozdrav.
V zákulisí org.restlet.jar
obsahuje všechna hlavní rozhraní pro toto API. The com.noelios.restlet.jar
obsahuje základní implementaci těchto rozhraní a poskytuje výchozí schopnost zpracování HTTP. S tímto modulem HTTP nebudete chtít přejít do výroby, ale pro účely vývoje a testování je to mimořádně výhodné. K otestování kódu RESTful nemusíte spustit hlavní kontejner. Výsledkem může být testování jednotek a integrace.
Ukázka v seznamu 1 používá k vytvoření výchozího nastavení hodně výchozího chování aplikace
instance (budu diskutovat aplikace
v dalším příkladu) a poslouchejte požadavky protokolu HTTP na portu 8182. The StreamServerHelper
třída začne poslouchat na tomto portu a odešle požadavky do Restlet
například jak přicházejí.
Cíl společnosti Louvel spočívající v podpoře RESTful Java na straně klienta je také snadno splněn, jak vidíte v seznamu 2.
Výpis 2. Klient Restlet
balíček net.bosatsu.restlet.basic; import java.io.IOException; import org.restlet.Client; import org.restlet.data.Protocol; public class SimpleClient {public static void main (String [] args) hodí IOException {String uri = (args.length> 0)? args [0]: "// localhost: 8182"; Klient klient = nový klient (Protocol.HTTP); client.get (uri) .getEntity (). write (System.out); }}
S SimpleServer
Spuštění tohoto nového klientského kódu se stejnými závislostmi JAR, které stále běží, by mělo vytisknout přátelský pozdrav do konzoly. Tisk výstupu v tomto stylu by samozřejmě nefungoval pro binárně orientované typy MIME, ale opět je to vhodný výchozí bod.
Příklad bez CRUD
Většina pedagogických příkladů REST zobrazuje služby CRUDish (vytváření, načítání, aktualizace, mazání) kolem jednoduchých objektů. Ačkoli tento styl určitě funguje dobře s REST, není to v žádném případě jediný přístup, který dává smysl - a většina z nás je unavená z příkladů CRUD. Následující příklad ukazuje základy aplikace Restlet zabalením kontroly pravopisu Jazzy open source.
REST je o správě informací, nikoli o vyvolání svévolného chování, takže při zvažování API zaměřeného na chování, jako je Jazzy, musíte být opatrní. Trik spočívá v zacházení s RESTful API jako s informačním prostorem pro slova, která existují a neexistují v používaných slovnících. Problém lze vyřešit různými způsoby, ale tento článek bude definovat dva informační prostory. /slovník
se používá ke správě slov ve slovníku. / kontrola pravopisu
se používá k hledání návrhů na slova podobná chybně napsaným slovům. Oba se zaměřují na informace zvážením absence nebo přítomnosti slov v informačních prostorech.
V architektuře RESTful by tento příkaz HTTP mohl vrátit definici slova ve slovníku:
ZÍSKAT // localhost: 8182 / dictionary /slovo
Pravděpodobně by vrátil kód odpovědi HTTP „Not Found“ pro slova, která nejsou ve slovníku. V tomto informačním prostoru je dobré označit, že slova neexistují. Jazzy neposkytuje definice slov, takže ponechám vrácení nějakého obsahu jako cvičení pro čtenáře.
Tento další příkaz HTTP by měl přidat slovo do slovníku:
PUT // localhost: 8182 / dictionary /slovo
Tento příklad používá DÁT
protože můžete zjistit, co je URI v /slovník
informační prostor by měl být předem a vydávat více DÁT
s by neměly dělat rozdíl. (DÁT
je idempotentní požadavek, jako DOSTAT
. Vydání stejného příkazu vícekrát by nemělo znamenat rozdíl.) Pokud chcete přidat definice, můžete je předat jako těla do DÁT
psovod. Pokud chcete v průběhu času přijmout více definic, možná budete chtít POŠTA
ty definice v, protože DÁT
je operace přepsání.
Nepřehlédněte synchronizaci
V zájmu zachování soustředění příkladů tento článek nevěnuje zvláštní pozornost synchronizačním problémům. Nezacházejte s výrobním kódem tak nonšalantně! Obraťte se na zdroj, jako je Souběžnost Java v praxi Pro více informací.
The Restlet
instance, které vytvořím, musí být svázány s příslušnými informačními prostory, jak je uvedeno v seznamu 3.
Výpis 3. Jednoduchá RESTful kontrola pravopisu
balíček net.bosatsu.restlet.spell; import com.swabunga.spell.event.SpellChecker; import com.swabunga.spell.engine.GenericSpellDictionary; import com.swabunga.spell.engine.SpellDictionary; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import org.restlet.data.Protocol; import org.restlet. *; veřejná třída SpellCheckingServer rozšiřuje aplikaci {public static String dictionary = "Restlet / dict / english.0"; public static SpellDictionary spellingDict; veřejný statický SpellChecker spellChecker; public static Restlet spellCheckerRestlet; public static Restlet dictionaryRestlet; static {try {spellingDict = new GenericSpellDictionary (nový soubor (slovník)); spellChecker = nový SpellChecker (spellingDict); spellCheckerRestlet = nový SpellCheckerRestlet (spellChecker); dictionaryRestlet = nový DictionaryRestlet (spellChecker); } catch (Výjimka e) {e.printStackTrace (); }} public static void main (String [] args) vyvolá výjimku {Component component = new Component (); component.getServers (). add (Protocol.HTTP, 8182); SpellCheckingServer spellingService = nový SpellCheckingServer (); component.getDefaultHost (). attach ("", spellingService); component.start (); } public Restlet createRoot () {Router router = new Router (getContext ()); router.attach ("/ spellchecker / {word}", spellCheckerRestlet); router.attach ("/ dictionary / {word}", dictionaryRestlet); zpětný směrovač; }}
Poté, co vytvoří instanci slovníku a kontrolu pravopisu, je nastavení Restletu ve výpisu 3 o něco složitější než v dřívějším základním příkladu (ale ne moc!). The SpellCheckingServer
je instance Restletu aplikace
. An aplikace
je organizační třída, která koordinuje nasazení funkčně propojených Restlet
instance. Okolí Součástka
ptá se aplikace
pro jeho kořen Restlet
voláním createRoot ()
metoda. Kořen Restlet
vrácené označuje, kdo by měl reagovat na externí požadavky. V tomto příkladu volala třída Router
slouží k odeslání do podřízených informačních prostorů. Kromě provedení této kontextové vazby nastavuje vzor adresy URL, který umožňuje, aby byla část „slova“ adresy URL k dispozici jako atribut na vyžádání. To bude využito v Restlet
jsou vytvořeny v seznamech 4 a 5.
The DictionaryRestlet
, uvedený v seznamu 4, odpovídá za vyřizování požadavků na manipulaci s /slovník
informační prostor.