1 Univerzita Hradec Králové Fakulta informatiky a managementu Remoting na platformě mobilní Javy Diplomová práce Ondřej Berger duben 20092 Univerzita ...
Univerzita Hradec Králové Fakulta informatiky a managementu
Remoting na platformě mobilní Javy
Diplomová práce
Ondřej Berger
duben 2009
Univerzita Hradec Králové Fakulta informatiky a managementu Katedra informatiky a kvantitativních metod
Remoting na platformě mobilní Javy
Diplomová práce
Autor: Ondřej Berger Informační management Vedoucí práce: Mgr. Tomáš Kozel, PhD.
Hronov
duben 2009
Prohlášení Prohlašuji, že jsem diplomovou práci zpracoval samostatně a s použitím uvedené literatury.
V Hronově dne 22.4.2009
Ondřej Berger
Poděkování Rád bych na tomto místě poděkoval Mgr. Tomáši Kozlovi, Ph.D. za vedení této diplomové práce a doporučení, která mi poskytl. Dále bych rád poděkoval všem, kteří mě v mé práci podporovali a poskytli mi připomínky a rady.
Anotace Tato diplomová práce „Remoting na platformě mobilní Javy“ se zabývá řešením komunikace a přenosu dat mezi serverem a mobilním zařízením disponujícím prostředím Jave ME. V první části přibližuje pojem remotingu, architekturu a prostředí, které se týká mobilních zařízení. Hlavní částí je zpracování a vyzkoušení jednotlivých metod, které lze v Jave ME použít, z pohledu vývojaře. Zabývá se způsobem použití
technologií Burlap, Hessian,
JSR 172, knihovny KSoap2, RMI a REST architektury, a dále skutečnostmi, které je třeba zvážit při jejich nasazení. Ukazuje řešení při serializaci a čtení objektů a
zmiňuje i
problematiku bezpečnosti. Na základě těchto informací lze rozhodnout, která metoda se jeví jako vhodná při řešení konkrétní aplikace. Součástí práce je modelová aplikace se všemi metodami a možným řešení serverové části s využitím současných technologií, jako je Spring framework.
Annotation This thesis „Mobile Java remoting“ is focused on communication and transferring data between computer server and mobile device with J2ME platform. First part is dedicated to a remoting, architecture and environment related to mobile devices. Main part of this thesis is dedicated to a developers view of working and trying remoting methods available on Java ME. It process using of Burlap, Hessian, JSR 172, KSoap2 library, RMI and REST approach. It means facts to consider their usage. Shows how to use this methods to serialize a read objects as well as security. From these facts can be decided which method of remoting is suitable solution for real application. A part of this thesis is an exemplar application that shows using of all methods as well as possible solution of server using modern technologies like Spring framework.
Obsah Úvod..........................................................................................................................................8 1. Remoting................................................................................................................................9 2. Remoting na mobilních zařízeních......................................................................................11 2.1 Mobilní zařízení............................................................................................................11 2.1.1 Prostředky mobilních zařízení...............................................................................11 2.2 Architektura řešení s mobilním klientem......................................................................12 2.2.1 Přímá komunikace serveru s klientem...................................................................14 2.2.2 Komunikace s využitím middleware.....................................................................14 3. Java ME (J2ME)..................................................................................................................16 3.1 CLDC konfigurace........................................................................................................17 3.1.1 Specifikace a API..................................................................................................17 3.1.2 Profil MIDP...........................................................................................................18 3.1.3 Volitelné balíčky....................................................................................................19 3.2 CDC konfigurace...........................................................................................................20 3.2.1 Specifikace a API..................................................................................................20 3.2.2 Profily....................................................................................................................21 3.2.3 Volitelné balíčky....................................................................................................24 4. Remoting na J2ME klientu..................................................................................................26 4.1 Burlap............................................................................................................................26 4.1.1 Implementace J2ME Burlapu................................................................................27 4.1.2 Použití Burlapu......................................................................................................28 4.1.3 Serializace dat........................................................................................................30 4.1.4 Obsluha vyjímek a zabezpečení.............................................................................31 4.2 Hessian..........................................................................................................................32 4.2.1 Implementace Hessianu na J2ME..........................................................................33 4.2.2 Použití Hessianu....................................................................................................33 4.2.3 Serializace dat........................................................................................................35 4.2.4 Obsluha vyjímek a zabezpečení.............................................................................36 4.3 J2ME Web services (JSR 172)......................................................................................36 4.3.1 Webové služby......................................................................................................36 4.3.2 SOAP zpráva.........................................................................................................37 4.3.3 Webové služby na J2ME.......................................................................................38
4.3.4 JSR 172 API subset...............................................................................................39 4.3.5 Použití JSR 172.....................................................................................................39 4.3.6 Obsluha vyjímek....................................................................................................43 4.3.7 Zabezpečení...........................................................................................................43 4.4 kSOAP2.........................................................................................................................44 4.4.1 Použití kSOAP2 ....................................................................................................44 4.4.2 Serializace a deserializace komplexních objektů..................................................47 4.5 RMI (JSR 66)................................................................................................................52 4.5.1 RMI na J2ME........................................................................................................53 4.5.2 Použití RMI...........................................................................................................54 4.5.3 RMI class loader....................................................................................................55 4.5.4 Ošetření vyjímek....................................................................................................55 4.5.5 Zabezpečení ..........................................................................................................55 4.6 REST architektura.........................................................................................................56 4.6.1 J2ME REST klient.................................................................................................57 4.6.2 Ošetření vyjímek....................................................................................................59 4.6.3 Zabezpečení...........................................................................................................59 5. Server pro J2ME klienty......................................................................................................60 5.1 Nastaveni HTTPS na Apache Tomcat...........................................................................60 5.2 Burlap a Hessian server.................................................................................................60 5.3 Server pro webovou službu...........................................................................................61 5.4 RMI server.....................................................................................................................61 5.5 REST server..................................................................................................................62 6. Modelový příklad.................................................................................................................63 6.1 Klientská část................................................................................................................63 6.1.1 CDC.......................................................................................................................64 6.1.2 CLDC.....................................................................................................................64 6.2 Serverová část................................................................................................................64 6.3 Nastavení CLDC simulátoru.........................................................................................65 6.4 Nastavení CDC simulátoru............................................................................................65 7. Výsledky..............................................................................................................................66 8. Závěr....................................................................................................................................68 Seznam použité literatury........................................................................................................70 Seznam obrázků......................................................................................................................74
Úvod
Úvod V dnešní době je nezbytné pro většinu podnikajících firem i dalších institucí mít k dispozici informační systém, který bude podporovat její podnikové aktivity a umožní jí efektivní alokaci zdrojů, řešení administrativy a podporu rozhodování. Ne všechny operace a procesy závislé na informačním systému jsou časově kritické, nicméně v případech řešení problémů přímo v terénu může být přístup k informačnímu systému prostředkem, který značně situaci ulehčí. V drtivé většině případů je k dispozici mobilní telefon, či digitální osobní asistent v kombinaci s telefonem. Signálem mobilních sítí je pokryto prakticky celé území republiky a je tak k dispozici přístup k telefonní a zároveň i datové síti. To postačuje mobilnímu zařízení, aby se s využitím vhodné aplikace mohlo připojit k informačnímu systému firmy a svému uživateli poskytnout potřebné informace. Cílem této práce je prozkoumat možné přístupy k implementaci takového mobilního klienta a jejich použití z pohledu vývojáře systému. Bude použita platforma mobilní Javy - J2ME, což je prostředí, které je dostupné v široké škále zařízení. V první části bude stručně popsán remoting obecně. Následovat bude popis mobilních zařízení, dvě základní architektury pro řešení klienta a aplikační prostředky, které poskytuje Java ME jako platforma. Největší část práce bude věnována způsobu použití vybraných metod z pohledu vývojáře - co je nezbytné pro použití metody, jak přenášet objekty, seznamy a vyjímky, jak přenos zabezpečit a jak lze vytvořit server. Následovat bude stručný popis modelové aplikace, na které jsou metody vyzkoušeny. Součástí práce je také funkční implementace mobilního klienta, který s využitím různých metod dokáže komunikovat se serverem.
8
1.Remoting
1. Remoting Výklad pojmu remoting může být nejednoznačný. V této práci je remotingem myšlen způsob přenosu dat (objektů) mezi komunikujícími částmi v rámci systému, v podstatě se jedná o tzv. distribuované výpočty. Ty zahrnují hardwarové a softwarové systémy, které obsahují více prvků, procesů nebo programů, které fungují a spolupracují v rámci méně nebo více řízeného režimu.[1] Cílem je propojení prvků, jejich efektivní využívání a možné rozšiřování dostupných zdrojů. Takové řešení je pak odolnější vůči selháním a je výkonnější než samostatné počítačové systémy. Distribuované
výpočty
pokrývají
různé
softwarové
i
hardwarové
architektury,
počínaje komunikací mezi procesorovými výpočetními jednotkami (CPU). Na vyšší úrovni pak je nezbytné zajistit komunikaci mezi procesy a programy, které jsou spuštěny na těchto CPU. Řešení archtiektury distribuovaných výpočtů často spadá do jedné z následujících architektur (vybráno z [1]): •
Klient – server, kdy klientský kód žádá o data server, a tato data zobrazuje uživateli.
•
Tří a vícevrstvá architektura umožňuje přesunout většinu logiky klientské na další vrstvy a použít tak tenkého bezstavového klienta.
•
Clusterování zahrnuje soustavu strojů, které úzce spolupracují a paralelně sdílí běžící proces. Proces je rozdělen na části, které řeší jednotky v clusteru a které jsou nakonec složeny do konečného výsledku.
•
Peer-to-peer proti tomu nemá žádný centrální prvek, který by řídil správu zdrojů. Všechny komunikující prvky (peers) mají stejnou odpovědnost a mohou sloužit jako server i jako klient.
9
1.Remoting K zajištění spolupráce se užívá některé z technik mezi-procesové komunikace, pomocí které se vyměňují data mezi procesy.([1]) Pokud procesy běží na počítačích, které jsou spojeny počítačovou sítí, užívá se často model tzv. vzdáleného volání procedur (Remote Procedure Call – RPC), který umožňuje klientské straně volat metody rozhraní serveru, předávat data a získat odpověď. Existuje více způsobů komunikace, některé z nich jsou platformě nezávislé a je možné tedy komunikovat po síti mezi aplikacemi, které jsou napsané v různých jazycích jako je Java, .NET, Flash nebo třeba i JavaScript. Mezi takové patří dle [2] např.: •
Common Object Request Broker Architecture (CORBA),
•
XML RPC,
•
webové služby nad SOAP protokolem,
•
nebo Unixové sockety.
Dále existují i řešení, která nejsou interoperabilní a váží se na konkrétní platformu příp. programovací jazyk. Mezi ně patří mj.: •
Java Remote Method Invocation (RMI),
•
Component Object Model (COM) od Microsoftu, resp. Distributed Component Object Model (DCOM),
•
.NET remoting,
•
a některé další.
K řešení komunikace mezi počítači je tak k dispozici poměrně velké množství postupů a na ně vázaných protokolů. Některé z těchto metod (jako např. webové služby nebo RMI) jsou dostupné pro systémy, které vyžadují existenci i mobilních klientů, tedy prvků systému, které nejsou pevně svázány s počítačovou sítí a slouží uživatelům i pro práci v terénu. Jejich prostředky jsou omezenější a k zajištění komunikace je tak nutné řešit některé specifické otázky.
10
2.Remoting na mobilních zařízeních
2. Remoting na mobilních zařízeních 2.1 Mobilní zařízení Pod pojmem mobilní zařízení jsou v této práci rozuměna přenosná zařízení [3] s hardwarovými a softwarovými prostředky umožňujícím svým uživatelům zejména hlasovou komunikaci s okolím prostřednictvím bezdrátové sítě. Jedná se hlavně o mobilní telefony a kombinace mobilního telefonu s digitálním asistentem (PDA). Prakticky všechna současná zařízení zvládají kromě hlasových přenosů i přenos dat. Datové přenosy se využívají např. k procházení Internetu a odesílání emailů využitím aplikací nabízených zařízením. Tyto přenosy jsou však dostupné i pro aplikace třetích stran, které lze do zařízení doinstalovávat. Nezáleží na platformě, kterou zařízení disponuje. S využitím odpovídajících vývojových prostředků je možné datově komunikovat z Windows Mobile, OS Symbian, Palm OS a také z platformy Java ME (Java Micro Edition), která je často dostupná i v zařízeních bez vlastního operačního systému. Java aplikace mohou podstatně rozšířit schopnosti zařízení a umožnit například jeho proměnu v klienta informačního systému.
2.1.1 Prostředky mobilních zařízení Mobilní zařízení nejsou plnohodnotné počítače a tedy ani plnohodnotná klientská zařízení. Prostředky, které jsou na nich k dispozici jsou např. v porovnání s notebooky (které lze v jistém smyslu také považovat za mobilní zařízení) mnohem skromnější. Komunikace s uživatelem Mobilní zařízení obvykle obsahují LCD displej s rozlišením QVGA (320x240 px1) ,v lepším případně VGA (640x480 px). Tomuto aspektu je nutné věnovat pozornost při návrhu ovládání a zobrazení grafických prvků. Je nutné rozlišovat i způsob ovládání zařízení a tomu přizpůsobit uživatelské rozhraní. Některá zařízení disponují pouze numerickou klávesnicí doplněnou několika funkčními tlačítky. To je případ většiny současných mobilních telefonů, bez ohledu na výrobce nebo model. 1 Pixel – zobrazovací bod
11
2.Remoting na mobilních zařízeních Zařízení vyšších tříd pro manažery, která jsou určena k častější práci v terénu mimo kancelář, pak někdy obsahují zmenšeninu QWERTY klávesnice, dotykový displej, případně oba tyto prvky. Jsou tak lépe připravena pro časté používání, jsou pohodlnější na ovládání a protože se u nich předpokládá i náročnější využití, jsou lépe vybavena po stránce hardwarové. Je zde výkonnější procesor, větší množství využitelné paměti a také lepší propojitelnost s okolím (nejen GSM sítě, ale také např. bezdrátové Bluetooth a Wi-Fi sítě). Komunikace s okolím Aby bylo možné zařízení využívat např. jako aplikačního klienta, nebo i k procházení webových stránek, je nutná podpora datových přenosů a jejich dostupnost aplikaci. Komunikace samotná probíhá v závislosti na poskytovateli služeb a možnostech zařízení. Komunikačním médiem je např. vytáčené CSD spojení, paketová data GPRS nebo EDGE, v případě pokrytí pak i sítě dalších generací 3G nebo 4G. V případě zařízení vyšších tříd je možné využít i dostupné Wi-Fi sítě. Výkon zařízení Pro vývojáře mobilních aplikací jsou, kromě způsobu ovládání a komunikace, důležité i prostředky, které zařízení nabízí a které lze v aplikaci používat. Jedná se hlavně o procesor (jeho rychlost) a dostupnou paměť. Oba tyto aspekty je při vývoji vždy nutné zohlednit a co nejefektivněji využívat. To přirozeně platí i v případě aplikací pro běžné počítače, ale v mobilních zařízeních je tento fakt mnohem kritičtější.
2.2 Architektura řešení s mobilním klientem Na rozdíl od „klasického“ remotingu, který se užívá i k peer-to-peer spojení a řešení distribuované architektury, v prostředí mobilních zařízení je nejčastějším modelem klientserver, nebo vícevrstvé řešení. Mobilní zařízení zde vystupuje v roli klienta, který zasílá požadavky na server s mobilním rozhraním, a zobrazuje výsledky uživateli.
12
2.Remoting na mobilních zařízeních K výše zmíněným omezením mobilních zařízení je nutno přihlížet již při návrhu celého architektonického řešení. Nejvíce limitující je skutečnost, že mobilní zařízení disponují omezeným množstvím paměti. Druhým omezením, které souvisí s přenosem dat do mobilního přístroje, je nepředvídatelnost rychlosti, ale i dostupnosti připojení a tedy neznámý čas, který přenos zabere. Mobilní přístroj se nemusí nacházet v oblasti s pokrytím rychlými daty mobilních sítí (Wi-Fi, 3G), mohou být dostupná pouze paketová data s využitím GPRS, nebo dokonce pouze vytáčená připojení (CSD). I přenos malého množství dat tak může trvat poměrně dlouhou dobu. Oba tyto aspekty (omezenou paměť a nepredikovatelnou rychlost řádově spíše v jednotkách kB) je nutno brát v úvahu při návrhu rozhraní, které bude dostupné mobilním klientům. Bez ohledu na dva možné způsoby řešení přístupu je žádoucí maximálně omezit přenášená data. Toho lze docílit například i využitím některých z níže uvedených postupů: •
Zavedením zvláštních DTO2 objektů pro komunikaci s klientem, které obsahují pouze nezbytně nutná data.
•
Návrhem rozhraní, které umožní načítání objektů až v okamžiku potřeby na klientu (například načítání agregovaných objektů pro rodičovský objekt).
•
Přenos s využitím protokolu, který má minimální režii při přenosu, tedy upřednostnit, je-li to možné, binární protokol před XML apod.
•
Využitím komprese přenášených dat.
Některé přístupy (např. komprese) jsou závislé na platformě, pro kterou je klient vyvíjen, a to samozřejmě ovlivní i konečný návrh. Výše zmíněné řešení komunikace mezi počítačem a mobilním přístrojem platí i pro možné architektury, které lze aplikovat při budování informačního systému s mobilním klientem. Mohou nastat v zásadě tři situace: •
vývoj nového systému,
•
přidání mobilních klientů k systému existujícímu s využitím rozhraní pro jiné (nemobilní) vzdálené klienty,
2 Data Transfer Object
13
2.Remoting na mobilních zařízeních •
přidání mobilních klientů k systému, který žádné vzdáleně přistupující klienty nemá.
První případ je ideální a umožňuje již v počátku návrhu počítat s limity mobilních klientů a přizpůsobit tomu celý návrh. V druhém případě je možné i bez invazivního zásahu do stávajícího systému vytvořit middleware server, který bude překládat požadavky mezi mobilním klientem a rozhraním serveru, které je připraveno pro „plnohodnotné“ aplikační klienty. Bez nutnosti zásahu do kódu je tak možné rozšířit přístup do stávajícího sytému. V posledním případě, kdy není vystaveno žádné vzdáleně přístupné rozhraní je nutné provést úpravu stávající aplikace tak, aby zpřístupnila buď přímo odlehčené mobilní rozhraní, nebo rozhraní pro middleware.
2.2.1 Přímá komunikace serveru s klientem Toto řešení je možné snadno realizovat pouze v případě, kdy se s mobilním klientem počítá již při návrhu nového systému. Pro mobilní klienty je navrženo specializované, odlehčené, vzdáleně dostupné rozhraní a již ve fázi návrhu bussines logiky systému se připraví podmínky pro jeho využívání. Mohou zde být metody a postupy pro konverzi doménových objektů do menších transportních, řešení komprese apod.
Obrázek 1: Přímá komunikace klienta a serveru Mobilní zařízení, klient, pak komunikuje přímo se serverem, bez dalších konverzí a překladů dat na cestě, zde ale mohou nastat problémy v případě vysoké zátěže serveru a je nutné zvážit i bezpečnostní hledisko tohoto přístupu.
14
2.Remoting na mobilních zařízeních
2.2.2 Komunikace s využitím middleware Architekturu s využitím middleware komponent je možné realizovat jak v případě návrhu nového systému, tak i při integraci mobilních klientů do systému stávajícího, který umožňuje vzdálený přístup pro běžné aplikační klienty.
Obrázek 2: Komunikace klienta s využitím middleware serveru Middleware server přebírá část zátěže způsobenou mobilními klienty a na server zasílá standardní požadavky (závisející na zvolené metodě komunikace) jako ostatní klienti. Nedochází tak k redukci zátěže co do počtu klientů, resp. požadavků, ale dochází k rozložení zátěže v oblasti konverze, kterou řeší middleware místo aplikačního serveru.
15
3.Java ME (J2ME)
3. Java ME (J2ME) Java Micro Edition (Java ME) je soubor specifikací a technologií, které mohou být kombinovány za účelem vytvoření platformy splňující požadavky kladené na mobilní zařízení jako jsou mobilní telefony, zabudovaná zařízení a spotřební produkty. [4] Platforma mobilní Javy (též Java Mobile, Java ME) je založena na třech elementech: •
konfigurace (configuration) obsahuje základní knihovny, které poskytuje JVM (Java Virtual Machine) pro co nejširší základnu zařízení,
•
profil (profile) zahrnuje množinu API (Application Programming Interface) pro užší skupinu zařízení, a
•
volitelné balíčky (optional packages), které poskytují API pro specifické technologie.
Celá Java ME je rozdělena do dvou základních konfigurací, jednu pro potřeby malých mobilních zařízení jako jsou mobilní telefony, a druhou, která je zaměřena na výkonnější přístroje jako PDA či set-top boxy.
Obrázek 3: Komponenty J2ME (převzato ze [4])
16
3.Java ME (J2ME)
3.1 CLDC konfigurace Conection Limited Device Configuration (CLDC) je základní částí platformy Java ME. Zaměřuje se na standardizování vysoce přenosných zařízení s omezenými zdroji. Vývoj platformy se řídí tzv. JCP (Java Comunity Process), do kterého je zapojeno přes 500 výrobců zařízení, mobilních operátorů, dodavatelů softwaru a dalších subjektů. Mezi typická zařízení patří mobilní telefony, PDA apod. CLDC je konfigurace (viz. elemety platformy výše). Podporovaným (a prakticky jediným) profilem je tzv. MIDP - Mobile Information Device Profile. Volitelné balíčky rozšiřující funkčnost, jsou pak závislé na schopnostech konkrétního zařízení a na jeho výrobci.[5]
3.1.1 Specifikace a API Specifikace CLDC 1.0 platformy byla schválena v srpnu 1999, a vydána jako JSR 3 30. Novější verzí je CLDC 1.1, která přináší rozšíření pro novější zařízení a přidává nové funkce, zejména pak pro aritmetiku v plovoucí desetinné čárce (typy float a double). Byla vydána roku 2002 jako JSR 139 a je dostupná na většině současných zařízení. Každá Java aplikace,bez ohledu na to zda je mobilní či serverová, potřebuje ke svému běhu virtuální stroj JVM. V případě konfigurace CLDC se používají dvě varianty JVM: •
KVM (Kilobyte Virtual Machine) je původní, starší verze,
•
HotSpot Implementation VM je nověji implementovaná verze virtuálního stroje, která přináší několikanásobně vyšší výkon díky částečné předkompilaci kódu.
API, které nabízí CLDC 1.1 konfigurace pro vývojáře, zahrnuje úzkou podmnožinu balíčků a tříd, které nabízí J2SE 1.3 [6]: java.io Je základním balíčkem, který poskytuje třídy pro obsloužení vstupu a výstupu dat s využitím tzv. streamů (proudů). Potomci abstraktních tříd InputStream a OutputStream umožňují práci s primitivními datovými typy, děděním z tříd Reader a Writer jsou odvozeny třídy pro práci s řetězcovými proudy. Zahrnuta je i hiearchie vyjímek související se vstupem a výstupem dat (např. IOException) 3 Java Specification Request – popisy jednotlivých specifikací pro celou Java platformu (nejen Java ME)
17
3.Java ME (J2ME) java.lang , java.lang.ref Tento balíček obsahuje objektové wrappery pro primitivní datové typy a třídy pro práci s řetězci (String, StringBuffer). Kromě toho je zde podpora pro vlákna, implementací rozhraní Runnable, nebo děděním od třídy Thread. Dále jsou zahrnuty známé vyjímky jako NullPointerException, ClassCastException a další. java.util Zahrnuje třídy pro práci s časem (Date, Calendar) a práci s kolekcemi (Vector). javax.microedition.io Tento balíček zahrnuje tzv. Generic Connection framework, tedy utility poskytující komunikaci nejčastěji prostřednictvím sítě. Jedná se o sadu rozhraní definující druh spojení (InputConnection, DatagramConnection atd.) a třídu Connector, která s využitím návrhového vzoru factory umožňuje vytvářet jednotlivé druhy spojení.
3.1.2 Profil MIDP Nad konfiguracemi stojí další rozšiřující sady knihoven a API, tzv. profily. Jak bylo zmíněno výše, v zásadě jediným profilem pro CLDC je Mobile Information Device Profile (MIDP). Profil MIDP existuje ve dvou verzích. Verze 1.0 je definována v JSR 37. Verze 2.0 (JSR 118) přináší oproti verzi 1.0 vylepšení a nové vlastnosti do oblasti multimédií a her, komunikační vylepšení a dokonalejší uživatelské rozhraní. Zachovává přitom zpětnou kompatibilitu s verzí 1.0. Tedy aplikace pro verzi 1.0 je možné spustit i v prostředí verze 2.0. Poslední zveřejněnou verzí je MIDP 2.1, která upravuje chování některých tříd, zejména třídy Canvas a některých dalších zobrazovacích a ovládacích prvků proti verzi 2.0. V API [7] profilu MIDP jsou zahrnuty i balíčky z CLDC konfigurace, které jsou v některých případech doplněny o nové třídy a rozhraní. Následující stručný přehled vybírá některé balíčky z verze 2.0.
18
3.Java ME (J2ME) javax.microedition.io Tento balíček obsahuje další rozhraní, která rozšiřují možnosti připojení z CLDC balíčku. Jedná se např. o SocketConnesion, HttpConnection i zabezpečené varianty jako HttpsConnection. javax.microedition.lcdui Zde jsou obsaženy třídy pro tvorbu uživatelského rozhraní a jednotlivé vysokoúrovňové komponenty, které poskytuje přímo MIDP 2.0 a jsou dostupné bez ohledu na výrobce zařízení. (TextField, Canvas, Image). Záleží na konkrétním řešení přístroje, jak jsou komponenty implementovány. V podbalíčku game se nachází podpůrné třídy pro tvorbu her jako GameCanvas nebo Sprite, které implementují některou základní funkčnost požadovanou ve hrách jako např. animace. javax.microedition.media Balíček zahrnuje technologie a třídy přímo kompatibilní s JSR 135, tzv. Mobile Media API (MMAPI). Dodává podporu pro multimédia, audio, video. javax.microedition.midlet Jediná třída obsažená v tomto balíčku - MIDlet, definuje aplikaci pro MIDP profil, a zajišťuje interakci mezi aplikací a prostředím ve kterém běží. javax.microedition.rms Zde jsou obsaženy třídy, rozhraní a vyjímky pro zajištění perzistence dat. Třída RecordStore obsahuje kolekci uložených záznamů v podobě polí bajtů, která zůstává dostupná i přes více spuštění MIDletu. Jedná se v podstatě o jednoduchou databázi, kterou lze použít k ukládání nastavení aplikace apod. javax.microedition.pki Rozhraní Certificate a CertificateException se vztahují k mechanismům komunikace s využitím zabezpečených spojení jako je HttpsConnection nebo SecureConnection .
19
3.Java ME (J2ME)
3.1.3 Volitelné balíčky Doplňující funkčnost a rozšíření konfigurace a profilů do celé J2ME platformy přinášejí tzv. optional packages, volitelné balíčky. V každém z těchto balíčků je dostupná jiná funkcionalita, kterou lze využít při vývoji mobilní aplikace. Ovšem využití může omezovat přenositelnost aplikace, protože ne všechna zařízení, která obsahují Javu, obsahují i všechny balíčky. Např. aplikace využívající Bluetooth nebude moci fungovat na zařízení bez této technologie.
Zde následuje seznam některých balíčků dle [8], které jsou dostupné na CLDC. •
Java APIs for Bluetooth (JSR 82)
•
Content Handler API (JSR 211)
•
Mobile Media API (JSR 135)
•
J2ME Web Services API (JSR 172)
•
Security and Trust Services APIs (JSR 177)
3.2 CDC konfigurace Conected Device Configuration (CDC) zahrnuje druhou konfigurací v rámci J2ME platformy. Je cílena na spotřební zařízení jako set-top boxy, navigace, výkonná PDA apod. Pro tuto konfiguraci jsou dostupné tři profily. Základní tzv. Foundation profile, doplňující Personal Basis Profile a Personal Profile. Na rozdíl od MIDP profilu u CLDC , nenabízí Foundation profile žádné uživatelské rozhraní, pouze poskytuje sadu základních API.
3.2.1 Specifikace a API Oproti CLDC je dle [9] (kap. 7.1) zaměřena na výkonnější zařízení, která mají 32bitový procesor a min. 2MB paměti dostupné pro Java VM. Disponují obvykle také trvalým síťovým připojením do TCP/IP prostředí Intranetu nebo Internetu.
20
3.Java ME (J2ME) Tato konfigurace obsahuje tzv. CVM virtuální stroj. Původně akronym pro Compact Virtual Machine, ovšem nyní písmeno „C“ neznačí nic. Schopnosti a možnosti CVM jsou blízké Java 2 Standard Edition (J2SE) 1.3. Základní rozdíly se dle [10] týkají zejména velikosti paměti a zobrazovacích možností. Konfigurace je nyní (leden 2009) ve verzi 1.1.2 a je specifikována v JSR 218. Předchozí verze 1.0 je specifikována v JSR 36. Samotná konfigurace je zpětně kompatibilní s CLDC 1.1, nabízí tedy i stejnou strukturu balíčků. Ty jsou doplněny o některé další a také jsou v určitých případech doplněny třídy do balíčků stávajících. Následuje seznam několika vybraných balíčků, které se v CLDC nenachází.(z [11]) java.lang.reflect Přidává podporu pro reflexi v jazyce Java. Tedy možnost pracovat s třídami, metodami, atributy jako objekty, které jsou instancemi tříd Class, Method, Field atd. java.net CDC jako jedna část J2ME platformy poskytuje trvalé připojení do sítě, a v tomto balíčku se nachází třídy pro podporu komunikace. Třídy URL, Socket, Inet4Address podstatně rozšiřují možnosti CLDC konfigurace, která je jinak poměrně omezená. Přidána je také podpora IPv6 protokolu (Inet6Addres). java.security, java.security.cert Tento balíček obsahuje podporu pro zabezpečení, práci s certifikáty (pomocí tříd Certficate), hashovací algoritmy MD5 nebo SHA s využitím MessageDigest tříd. java.util, java.util.jar, java.util.zip Oproti CLDC nabízí již konfigurace CDC i podporu prakticky celého Collecion Frameworku. Přidává tak rozhraní List a jeho implementace jako ArrayList, LinkedList. Dále je doplněno i několik implementací asociativních polí s využitím rozhraní Map (HashMap, TreeMap).
21
3.Java ME (J2ME) Je dostupná i sada tříd pro práci se ZIP archivy (ZipFile, ZipInputStream) a také pro manipulaci s JAR soubory, což jsou aplikační balíčky a knihovny platformy Java vycházející z formátu ZIP.
3.2.2 Profily Na rozdíl od CLDC, kde existuje pouze jediný profil, na CDC jsou dostupné tři. První z nich, Foundation Profile slouží jako základ pro zbývající dva profily Personal Profile a Personal Basis Profile. Foundation Profile (JSR 219) V kombinaci s CDC konfigurací přináší tento profil kompletní prostředí pro aplikace na omezených zařízeních, která nemají a nevyžadují standardizovaný systém pro GUI4. Může se jednat o tvorbu aplikací pro síťové tiskárny, routery, nebo enterprise aplikace. Profil má několik základních charakteristik: [12] •
Je založen na vyzkoušeném J2SE API, se kterým je seznámeno mnoho vývojářů, kteří tak mohou znalosti a zkušenosti s platformou znovu použít při vývoji produktů pro J2ME.
•
Profil je připraven a laděn pro zařízení s minimem prostředků.
•
Nemá podporu pro GUI, protože zařízení, pro která je určen, často tuto podporu nevyžadují. Pro tvorbu GUI v tomto profilu může být použito např. webové rozhraní, nebo proprietární systém, který je začleněn přímo do aplikačního prostředí (např. LCD displej).
Do konfigurace CDC doplňuje některé další balíčky a třídy (vybráno z [13]) : java.io
V tomto balíčku jsou doplněny zejména třídy pro práci se vstupem a výstupem řetězců. Jedná se např. o třídy CharArrayReader, StringWriter apod.
4 GUI – Graphic User Interface , grafické uživatelské rozhraní
22
3.Java ME (J2ME) java.net
Balíček pro práci se sítí je ve foundation profilu rozšířen zejména o možnost vytvoření serveru s využitím třídy ServerSocket, a dalších souvisejících tříd. java.security a podbalíčky
Bezpečnostní mechanismy a třídy jsou rozšířeny o podporu přístupových seznamů (ACL – Acces Control List) a mechanismy pro práci s digitálními podpisy DSA5 a asymetrické šifrování s privátním/veřejným klíčem RSA6. java.util a podbalíčky
Tento balíček rozšiřuje dostupné API např. o implementaci návrhového vzoru observer7 s využitím třídy Observeable a rozhraní Observer. Další doplnění se týkají např. práce s komprimačním formátem GZIP. javax.microedition.io
Obdobně jako balíček z CLDC obsahuje i tento různé druhy spojení jako HttpConnection, SocketConnection a jejich zabezpečené varianty. Navíc je zde pro potřeby serverů možné instanciovat implementaci ServerSocketConnetion rozhraní a vytvořit tak aplikaci naslouchající na určitém portu. Personal Basis Profile (JSR 217) Tento profil staví nad základním profilem a přidává mu zejména podporu pro standardizované uživatelské rozhraní v podobě základních prvků AWT8. Nezahrnuje ovšem komplexní komponenty jako jsou tlačítka, panely apod. K dispozici je pouze rámec (Frame), který je možné využít k vykreslování GUI. Využití tohoto profilu je v prostředích, kde není nutná podpora všech AWT komponent jako např. u interaktivní televize. Nabízí několik základních vlastností: [14]
5 6 7 8
•
GUI framework pro tvorbu jednoduchých nástrojů a
•
podporu pro tvorbu tzv. Xletů – obdoba Java apletů, běžící uvnitř kontejneru.
http://en.wikipedia.org/wiki/Digital_Signature_Algorithm http://en.wikipedia.org/wiki/RSA http://objekty.vse.cz/Objekty/Vzory-Observer AWT – framework pro tvorbu GUI
23
3.Java ME (J2ME) Seznam některých vybraných balíčků z [15] zahrnuje: java.awt a podbalíčky
Tento balíček poskytuje základní prvky pro tvorbu GUI jako je rámec (třída Frame), okno (Window), nebo grafický kontext Graphic, který poskytuje služby pro vykreslování obrázků, jejich transformace apod. java.rmi a podbalíčky
Zde je zahrnuto zejména rozhraní Remote, které označuje rozhraní, jehož metody mohou být volány vzdáleně. Při chybě ve volání dochází k vyvolaní zde definované RemoteException. javax.microedition.xlet a podbalíčky
V tomto balíčku a podbalíčcích jsou obsaženy třídy a rozhraní (Xlet) pro vytváření Xletů a další podpůrné třídy jako omezení (IxcPermission), nebo IxcRegistry pro zajištění komunikace mezi Xlety. Personal Profile (JSR 216) V tomto profilu je již implementováno plné AWT, které jej předurčuje do zařízení, kde je nezbytná podpora všech komponent. Tento profil je založen na Foundation profilu a zahrnuje i Personal Basis profil. Aplikace napsané pro tento profil jsou i dopředně kompatibilní s J2SE 1.4.2. ([16], kap. General requirements). Nabízí tři druhy aplikačních modelů (způsobů vytváření a spouštění aplikací) – applety, Xlety a užití metody public static void main(String []). Balíčky dostupné v tomto profilu jsou v zásadě shodné s těmi v Personal Basis profilu, ovšem jsou doplněny o nové třídy a komponenty, které zajišťují plnou podporu pro AWT (např. třída java.awt.Button). Doplněny jsou navíc pouze balíčky (z [16]): java.applet
Poskytuje podporu pro aplikační model appletu. Tedy třídu Applet, což je panel, který může být vložen např. do webové stránky. Informace nezbytné pro řízení appletu zajišťuje rozhraní AppletContext.
24
3.Java ME (J2ME) java.awt.datatransfer
V tomto balíčku je navíc doplněna zejména podpora pro schránku s využitím třídy Clipboard.
3.2.3 Volitelné balíčky Obdobně jako pro CLDC konfiguraci, i pro CDC jsou dostupné volitelné balíčky, které rozšiřují možnosti pro vývojáře přidáváním dalších funkcí. CDC RMI (JSR 66) Volitelný balíček pro Remote Method Invocation (RMI), dodává do
CDC podporu pro
komunikaci mezi dvěma Javovskými virtuálními stroji, které jsou navzájem dostupné po síti. Tento balíček je jedním z předmětů této diplomové práce a jedná se o metodu remotingu, která je dále vyzkoušena a popsána. CDC JDBC (JSR 169) Java Database Conectivity (JDBC) je sada definovaných rozhraní, která poskytují přístup k relačním databázím, resp. datovým zdrojům. Konkrétní implementace těchto rozhraní poskytují jednotliví dodavatelé a vývojáři databází. JDBC vrstva je tedy určitou abstrakcí nad konkrétním úložištěm, a výměnu databáze (např. PostgreSQL za DB2) lze vyřešit pouze změnou ovladače, bez nutnosti zásahu do zbývajícího kódu aplikace.9 Tento volitelný balíček je poměrně striktně omezen. Podmnožina balíčků a tříd, která vychází z J2SE JDBC API, je tak ochuzena o některé funkce, jako je třeba connection pooling, nebo se liší ve způsobu vytváření přístupu do databáze.[17]
9 Platí pokud nejsou využívány funkce, které jiná databáze neposkytuje (např. specifické SQL dotazy)
25
4.Remoting na J2ME klientu
4. Remoting na J2ME klientu Cílem této kapitoly je seznámit s metodami, které lze pro remoting použít na platformě Java ME. Budou rozebrány vybrané metody, ukázány možnosti a řešení některých situací, které tyto metody a protokoly přináší z pohledu vývojáře. Výběr konkrétní metody remotingu je pak závislý na konkrétním problému, uvažovaném systému a možnostech, které jsou k dispozici, zejména v oblasti klientských zařízení. Uvedený příklad, ke kterému se vztahují ukázky kódu a konfigurací je detailněji popsán v kapitole č. 6 zabývající se modelovou aplikací. Jeho architektura a objektová struktura je založena zejména na potřebách modelového řešení, na kterém by bylo možné realizovat více možností remotingu při zachování jednoho doménového modelu objektů. Při řešení „ostré“ aplikace by návrh probíhal s jiným cílem a tudíž i jinou výslednou architekturou, která by nezahrnovala další konverzi z přenesených objektů do doménových apod. Tato kapitola se bude zabývat řešením klientské části, možné řešení serveru bude zmíněno dále.
4.1 Burlap Burlap (doslovný překlad znamená hrubé plátno, plachtovinu nebo jutu) je jednoduchý protokol založený na XML, který lze použít pro komunikaci s webovými službami. Jedná se o malý protokol, který lze snadno používat i v prostředí J2ME, konkrétně i na CLDC konfiguraci určené např. pro mobilní telefony. [18] Za vývojem tohoto protokolu stojí společnost Caucho10, která vyvíjí i mj. open-source aplikační server Resin, nebo implementaci jazyka PHP napsanou v Javě (projekt Quercus). Burlap jako protokol byl vytvořen, aby umožnil i nejavovským klientům a serverům možnost spolupracovat s Enterprise Java Beans (EJB). Při návrhu tohoto protokolu bylo určeno několik hlavních cílů, které nový protokol musel splnit (vybráno z [19],[20]): •
Dostatečně pokrýt potřeby pro podporu EJB.
•
Používat co nejmenší možnou podmnožinu z XML.
10 http://caucho.com/
26
4.Remoting na J2ME klientu •
Nevyžadovat žádné externí definice schématu nebo IDL11.
•
Java služba by měla být dostupná jako servlet.
•
Musí být jednoduchý a snadno testovatelný.
•
Musí být co nejrychlejší.
Vše, co je tedy potřeba řešit v tomto ohledu, je serializace a deserializace libovolných Java objektů. To zahrnuje následující požadavky: •
Serializace primitivních datových typů.
•
Podpora „null“ hodnoty.
•
Sdílené a cyklické datové struktury.
•
Podpora objektů, polí, seznamů a asociativních polí (map).
•
Deserializace složených objektů.
•
Podpora ukazatelů na vzdálené objekty (odkazy na EJBHome a EJBObject).
Protokol je založen na tzv. SML (Simple Markup Language). SML je omezená podmnožina XML. Například neumožňuje používat zápis prázdného XML elementu pomocí . Jsou povoleny pouze elementy a znaková data. Nepoužívají se atributy elementů, jmenné prostory, komentáře a další komplikovanější záležitosti jako tzv. mixed content, nebo-li smíšený obsah, kdy element obsahuje znaková data a zároveň další elementy. Element smí obsahovat buď pouze další element, nebo znaková data, nikoliv však oboje najednou. Podrobnosti a kompletní specifikaci protokolu Burlap, včetně ukázkových serializací dat, lze nalézt na [19]. Dále se tato podkapitola bude věnovat použití tohoto protokolu na J2ME platformě, konkrétně na CLDC konfiguraci.
4.1.1 Implementace J2ME Burlapu Jak vyplývá ze specifikace protokolu, je to protokol relativně jednoduchý a nenáročný a přitom s dostatečnými možnostmi. Tyto vlastnosti ho dovolují použít i v CLDC konfiguraci. 11 Interface Definiton Language – popis rozhraní poskytovaného komponentou bez vazby na konkrétní jazyk, ve kterém je komponenta napsána. Např. WSDL dokumenty pro webové služby.
27
4.Remoting na J2ME klientu Je založen na tzv. RPC – Remote Procedure Call, neboli vzdáleném volání metody. To je architektonické řešení, kdy server na veřejném rozhraní vystavuje jednotlivé funkce a metody, které lze volat, předávat jim parametry a přebírat návratovou hodnotu. Všechna volání, a předávání hodnot jsou zapouzdřena a vyjádřena pomocí vybraného protokolu, v tomto případě Burlapu. Společnost Caucho nabízí vlastní implementaci Burlap protokolu pro J2ME, která je dostupná v JAR archivu s desktopovou verzí Hessian a Burlap protokolu. Verze 3.2.1 použitá v této práci
je
ke
stažení
na
adrese
http://hessian.caucho.com/#Hessian
%20Implementations/Download a dostupná je pod Apache licencí. Pro Java ME se jedná o balíček com.caucho.burlap.client, ze kterého stačí vyextrahovat následující třídy12: MicroBurlapInput
• •
MicroBurlapOutput
•
BurlapRemote
•
BurlapServiceException
•
BurlapProtocolException
V těchto třídách je obsažena kompletní implementace, kterou lze v J2ME používat. Burlap je protokol pro serializaci/deserializaci a implementace používá pro vstup a výstup standardní Java streamy (proudy). To umožňuje použít Burlap jak pro komunikaci přes síť, tak i pro pouhou serializaci například do textového souboru. Nejčastěji je ovšem řešena komunikace prostřednictvím sítě, proto se všechny příklady budou vztahovat pouze k ní. Jak použít serializaci do souboru, je uvedeno např. v [18], v sekci Burlap Serialization.
4.1.2 Použití Burlapu Pro vytvoření třídy MicroBurlapOutput, která zajistí serializaci objektu (případně MicroBurlapInput pro deserializaci), je nutné nejprve získat instanci příslušného streamu, který bude použit jako transport. V prostředí J2ME je často užíván protokol HTTP, který je přístupný prostřednictvím Generic connection frameworku z balíčku javax.microedition.io. 12 Je nutné použít zdrojovou distribuci JAR archivu, která obsahuje zdrojové kódy a ty zkompilovat s aplikací. Třídy z binárního archivu nelze použít na Java ME, protože jsou kompilovány pod J2SE JDK.
28
4.Remoting na J2ME klientu Připojení lze docílit např. následujícím fragmentem kódu, který je převzat ze vzorové aplikace, konkrétně třídy cz.berger.blog.client.impl.caucho.MicroBurlapClient, která slouží jako abstrakce pro zjednodušení volání Burlap serveru: HttpConnection httpConn; OutputStream os; MicroBurlapOutput output; String serverUrl = “http://localhost:8080/BlogServer/burlap.htm“; ... httpConn = (HttpConnection) Connector.open(serverUrl); httpConn.setRequestMethod(HttpConnection.POST); os = httpConn.openOutputStream(); output = new MicroBurlapOutput(os);
Nezbytné je nastavení HTTP metody na POST, protože požadavek na server (určený parametrem serverUrl) je posílán v těle požadavku, a není součástí URL jako v případě metody GET. Nyní je k dispozici instance třídy MicroBurlapOutput, kterou lze využít k zaslání požadavku na server. K zaslání požadavku je nezbytné pouze vyvolání jedné metody: output.call(“login“, new Object[] {“user”, “password”);
První parametr udává jméno volané metody, druhý parametr je pole objektů, které volaná metoda očekává jako svoje parametry. V poli musí být argumenty volané metody v tom pořadí, v jakém jsou uvedeny v hlavičce. V daném pořadí budou deserializovány na serveru a s využitím reflexe pak předány do příslušné metody na serverovém bussines objektu. Vrací-li volaná metoda nějakou návratovou hodnotu, lze ji přečíst, a to opět v Burlap formátu. K tomu je nutné po zaslání požadavku instanciovat objekt třídy MicroBurlapInput nad vstupním streamem příslušného HTTP spojení: InputStream is; MicroBurlapInput input;
29
4.Remoting na J2ME klientu … is = httpConn.openInputStream(); input = new MicroBurlapInput(is); Object result = input.readReply(expectedClass);
V objektu result je přečtená návratová hodnota, kterou zaslal server jako odpověď na volání metody. Parametr expectedClass je objekt třídy Class, která specifikuje druh třídy, která se očekává jako výsledek volání. Bude se jednat o primitivní datové typy, případně Vector.class pro vrácený seznam, nebo Hashtable.class pro vracené obecné objekty.
4.1.3 Serializace dat Protože konfigurace CLDC nenabízí možnosti reflexivního13 programování, jsou při serializaci nebo deserializaci jistá omezení, se kterými je nutno počítat. V případě primitivních datových typů jako jsou čísla, řetězce, nebo i např. datum je možné do parametrů metody call na třídě MicroBurlapOutput zapsat přímo tyto objekty (u primitivních datových typů je nutné použít jejich objektové wrapper třídy). Složitější situace nastává v případě komponovaných objektů (jako jsou např. instace třídy Post, z modelového příkladu). Ty obsahují více atributů, jako je nadpis, tělo příspěvku nebo seznam komentářů – dalších objektů. V případě serverové strany (uvažována je opět Java, edice alespoň J2SE), která komunikuje s využitím Burlapu, je vše automatické. Příslušná třída zodpovědná za serializaci zpracuje instanci třídy Post pomocí tzv. reflexe. Projde jednotlivé atributy a do výsledného proudu zapíše objekt příspěvku jako asociativní pole – mapu. Tedy vždy dvojici jména atributu a jeho hodnotu v příslušném formátu, který je dán protokolem (viz. [19]). Pokud je na klientské straně také J2SE, je opět pomocí reflexe vše vyřešeno. Pomocí zvláštního elementu v přenesené zprávě je získáno jméno třídy, kterou mapa reprezentuje. Ta je instanciována a její atributy naplněny hodnotami (v případě, že přenášené třídy splňují konvence tzv. Java Beans, tedy zejména bezparametrický konstruktor a gettery a settery pro atributy). 13 Možnosti Javy pracovat např. s objekty, atributy a metodami jako instancemi tříd Class, Field a Method. Podrobněji např. http://java.sun.com/docs/books/tutorial/reflect/index.html
30
4.Remoting na J2ME klientu U CLDC prostředí je ovšem situace jiná, reflexe zde není dostupná. Všechny objekty je nutné ručně převést na instance třídy Hashtable14 a zpět. Hashtable je asociativní pole, obdobně jako mapa (rozhraní Map) v J2SE. Zapouzdřuje dvojice klíč-hodnota. S hodnotou lze pracovat s využitím jejího unikátního klíče. Pokud nějaký objekt obsahuje další objekty (nebo seznam objektů), i tyto samozřejmě musí být převedeny na Hashtable. V
modelové
aplikaci
je
pro
tyto
účely
implementována
třída
cz.berger.blog.client.impl.caucho.BasicHashtableSerializer. Pomocí této implementace se jednotlivé doménové objekty převádějí na Hashtable a zpět (a to včetně agregovaných objektů a jejich seznamů). V případě implementace Burlapu společnosti Caucho, použité v této práci, bylo nutné pro správné serializování objektů na server upravit zdrojové kódy třídy MicroBurlapOutput. Konkrétně na řádcích 409-413 došlo k úpravě tak, aby ze zdrojové Hashtable byl zpracován zvláštní klíč (pod přidanou konstantou MicroBurlapOutput.TYPE_KEY ve zdrojové mapě), ve kterém je uloženo jméno třídy, která se serializuje. Toto jméno je pak při odesílání mapy zapsáno do odpovídajícího elementu dle specifikace protokolu Burlap. V původní implementaci se jméno třídy vůbec neserializuje a to na straně serveru přináší problémy. Objekty byly v některých případech (konkrétně třída Comment, agregovaná v třídě Post jako seznam příspěvků) instanciovány jako Hashtable, nikoliv jako třída Comment. Serializace polí, nebo seznamů objektů je v případě Burlapu bezproblémová. Jednotlivé prvky v seznamech jsou předávány do instance třídy Vector, ve které jsou pak vráceny. Pokud se jedná o obecné objekty, jsou ve výsledném seznamu opět asociativní pole (Hastable).
4.1.4 Obsluha vyjímek a zabezpečení Při práci s třídami MicroBurlapInput a MicroBurlapOutput je nutné ošetřit i vyjímky. V případě vyjímek IOException se jedná o chybu při přenosu dat, která nesouvisí s protokolem, a většinou ji nelze ovlivnit (například výpadek spojení).
4.Remoting na J2ME klientu Pokud metoda na serveru, resp. na bussines objektu vygeneruje vyjímku, dojde k serializaci této vyjímky a metoda readReply vyvolá BurlapServiceException. Tato třída umožňuje získat detaily o vyjímce, ke které na serveru došlo. Konkrétně pomocí svých metod getDetail(), getCode() a getMessage() lze získat potřebné informace a náležitě vyjímku zpracovat (např. zobrazením chybové zprávy uživateli). Dalším aspektem použití protokolu Burlap je bezpečnost. Protokol sám o sobě je snadno čitelný a neobsahuje žádné šifrovací mechanizmy. Počítačovou sítí prochází jako čistý text a je snadno odposlechutelný. V případě praktického nasazení je proto nutné zajistit přenos dat skrze stream, který je již šifrovaný (eventuelně i autentizovaný vhodným mechanizmem – např.
HTTP
basic
autentizací
jejíž
ukázka
je
dostupná
na
http://java.sun.com/docs/books/j2mewireless/examples/README.html). Pro šifrování obsahu je na MIDP profilu dostupná implementace protokolu HTTPS (Secured Hyper Text Transfer Protocol), což je varianta HTTP, která je zabezpečená pomocí certifikátů a principů asymetrické kryptografie. Použití je velice snadné a prakticky se neliší od výše uvedené nezabezpečené varianty. Místo rozhraní HttpConnection je použito přetypování na jeho potomka HttpsConnection, které navíc poskytuje i některé informace o certifikátu a zabezpečeném spojení obecně. Toto typování ovšem není nutné. I pro HTTPS lze použít přetypování na HttpConnection. Při zadávání URL serveru je pouze nutné uvést protokol https:// místo http://. Jak doplnit certifikát a umožnit HTTPS pro servletový kontejner Tomcat je uvedeno v kapitole č.5 , která se zabývá tvorbou serveru. Následující kód ukazuje vytvoření HttpsConnection. Další práce (získání streamů apod.) s tímto rozhraním je pak stejná jako s jeho nezabezpečenou variantou. HttpsConnection httpsConn; String serverUrl = “https://localhost:8080/BlogServer/burlap.htm“; ... httpsConn = (HttpsConnection) Connector.open(serverUrl);
32
4.Remoting na J2ME klientu
4.2 Hessian Stejně jako protokol Burlap, pochází i Hessian od společnosti Caucho. Na rozdíl od Burlapu je to protokol binární, ovšem slouží ke stejným účelům a to zajištění komunikace služeb s klienty. Stejně jako Burlap je i tento protokol možné použít pro tzv. RPC volání, ovšem od verze 2.0 Hessian přichází i s podporou tzv. messagingu (zasílání zpráv). Tato komunikace je asynchronní, na rozdíl od RPC, která je synchronní. Zasílání zpráv není závislé na architektuře klient-server, ani na volání metod. Na zprávy může a nemusí být zasílána odpověď a Hessian slouží pouze jako formát pro výměnu dat. Návrh celého protokolu byl podřízen obdobným požadavkům jako návrh Burlapu [21]. Jak již bylo zmíněno, protokol Hessian je binární a tedy není tak snadno čitelný pro uživatele, tak jako protokoly založené na XML. V Hessianu je možné serializovat následující data: •
Primitivní datové typy (String v UTF8, integer, long, double, boolean, datum v milisekundách a surová binární data),
•
hodnotu null,
•
pole (seznam) a asociativní pole (mapu),
•
obecný objekt,
•
odkaz pro sdílené objekty.
Kompletní seznam, a popis serializace dat lze nalézt na [22].
4.2.1 Implementace Hessianu na J2ME Obdobně jako v případě Burlapu, i u Hessianu 1.0 existuje řešení, která je dostupné i v prostředí CLDC zařízení. Vlastnosti protokol předurčují k obdobnému použití jako u Burlapu, ovšem protože je protokol binární, je zde menší režijní přenos a přenesená data jsou vyjádřena úsporněji. Obdobná je také realizace serveru, v podobě servletu. Na tento servlet přicházejí požadavky, které jsou zpracovávány opět ve stylu RPC.
33
4.Remoting na J2ME klientu Od společnosti Caucho je opět dostupná implementace pro Java ME, kterou lze stáhnout opět v jednom JAR archivu s oběma protokoly (viz. Burlap). I zde k použití stačí pouze několik tříd. Ty lze nalézt v následujících balíčcích: •
•
com.caucho.hessian.io ◦
HessianProtocolException
◦
HessianRemote
◦
HessianServiceException
com.caucho.hessian.micro ◦
MicroHessianInput
◦
MicroHessianOutput
Stejně jako v případě Burlapu je nutné zkompilovat tyto třídy spolu s aplikací a nepoužívat třídy již kompilované.
4.2.2 Použití Hessianu Logika tříd je obdobná jako v případě a vytvoření MicroHessianInput a MicroHessianOutput instancí je opět závislé na získání streamu. V příkladu je opět použit protokol HTTP. (Ukázky pocházejí z třídy cz.berger.blog.client.impl.caucho.AbstractHessianClient). HttpConnection httpConn; OutputStream os; MicroHessianOutput output; String serverUrl = “http://localhost:8080/BlogServer/hessian.htm“; ... httpConn = (HttpConnection) Connector.open(serverUrl); httpConn.setRequestMethod(HttpConnection.POST); os = httpConn.openOutputStream(); output = new MicroHessianOutput(os);
34
4.Remoting na J2ME klientu V zásadě je zde situace stejná jako v případě Burlapu. Ovšem zaslání požadavku již s využitím implementace od Caucha není tak jednoduché. Je proto vhodné vytvořit nějakou abstrakci nad komunikačními třídami, která vývojáře odstíní od opakujících se částí kódu. Na MicroHessianOutput již není dostupná zjednodušující metoda call jako u Burlapu. Třídy týkající se Hessianu se zdají v porovnání s Burlapem nedokončené a v posledních několika vydáních se měnily pouze nepatrně. Pro vyvolání metody a předání parametrů se použije následující kód: output.startCall(methodName); output.writeObject(object); output.completeCall();
Tím se na server zapíše zahájení volání metody s daným jménem, zapíše se jeden parametr a volání se dokončí. Metoda writeObject detekuje třídu zapisovaného objektu a zapíše jej tak ve správném formátu. Akceptuje i předání null hodnoty. Pro čtení odpovědi je nutné instanciovat MicroHessianInput nad příslušným vstupním proudem. InputStream is; MicroHessianInput input; ... is = httpConn.openInputStream(); input = new MicroHessianInput(is);
Čtení je potom opět podobné jako zápis, tedy zahájení čtení odpovědi, přečtení vráceného objektu a ukončení čtení odpovědi. input.startReply(); Object reply = input.readObject(expectedClass); input.completeReply();
Jako parametr metody readObject se předává třída, která je očekávána jako vracená.
35
4.Remoting na J2ME klientu
4.2.3 Serializace dat Protokol Hessian jako takový má v zásadě stejné možnosti jako XML Burlap. Umožňuje tedy serializovat primitiva, objekty i seznamy. Problém se nachází v případě jeho J2ME implementace. V té, konkrétně u třídy která čte odpověď (MicroHessianInput), se prozatím nenachází podpora pro jinou formu, než primitivní datové typy. Deserializace objektů v podobě asociativního pole – Hashtable, nebo seznamu – Vector, není v době psaní této práce implementována. Jedním z možných řešení je implementováno v modelové aplikaci. Hessian je užit jako transportní protokol a interface na serverové části je upraven tak, aby přijímal všechny požadavky jako řetězce (nebo čísla). Všechny řetězcové parametry a návratové hodnoty obsahují data serializovaná ve formátu JSON. JavaScript Object Notation (JSON) JSON je nenáročný formát pro výměnu dat [23]. Je čitelný pro uživatele a zároveň snadno zpracovatelný počítačově. Jedná se o řetězcové vyjádření v podstatě libovolných dat a objektů. Spadá do kategorie dynamicky typovaných metaprotokolů stejně jako Hessian [24]. Jeho řešení a snadný formát ho umožňují použít i na omezené platformě mobilní Javy. Jiný protokol (Hessian), nebo architektura je pak použit pouze jako transport pro řetězec s daty v JSON formátu. Pro platformu J2ME existuje několik implementací. V praktické části této práce je použita implementace
od
JSON.org
(http://www.json.org/java/org.json.me.zip
pro
klienta,
a http://www.json.org/java/index.html pro serverovou část). Toto řešení umožňuje serializovat objekty (v případě J2ME pak instance Hashtable) i seznamy do JSON formátu a zpět. V modelové práci je pak k implementaci rozhraní JsonSerializer využito i instance HashtableSerializer pro převod doménových objektů do Hashtable a zpět a poté z Hashtable do JSON řetězce a zpět. K práci s JSON formátem s využitím těchto knihoven slouží instance tříd JSONObject, JSONArray apod. Užití této knihovny je zpracováno v modelovém příkladu a to jak na klientu,
tak
na
serveru
v
třídách
cz.berger.blog.server.json.JsonSerializerImpl
a cz.berger.blog.client.json.JsonSerializerMEImpl. 36
4.Remoting na J2ME klientu
4.2.4 Obsluha vyjímek a zabezpečení Hessian v prostředí J2ME nabízí obdobně jako Burlap třídu HessianServiceException, která poskytuje detaily o vyjímce, ke které došlo na bussines objektu serveru. Ovšem v nynější implementaci knihoven (verze 3.2.1) tato výjimka není nikdy generována. Dochází pouze k IOException, která se vztahuje ke komunikačnímu médiu, nikoliv k samotnému protokolu. V modelové aplikaci, kdy je Hessian pouze jako transportní protokol, je proto serverová výjimka serializovaná také do JSON formátu. V implementaci rozhraní JsonSerializer (třída JsonSerializerMEImp) je poté v metodě checkForRemotedException(String) kontrolováno, zda řetězec s odpovědí neobsahuje vyjímku ze serveru. Možnosti zabezpečení Hessian protokolu jsou obdobné jako v případě Burlapu. Je-li transportem HTTP protokol, je možné realizovat i zabezpečený přenos přes HTTPS. Implementace je obdobná jako v Burlapu a lze jej nalézt v modelové třídě AbstractHessianClient.
4.3 J2ME Web services (JSR 172) Popis tzv. webových služeb (WS - Web Services) není předmětem této práce. Proto bude zmíněn jen velmi stručný základní princip webových služeb a většina textu bude věnována použití WS na mobilních zařízeních.
4.3.1 Webové služby Webové služby jsou aplikační komponenty, které umožňují komunikaci prostřednictvím otevřených protokolů. Mohou tak být používány jinými aplikacemi a komponentami s využitím vzdáleného přístupu přes počítačovou síť. Častou realizací webových služeb je kombinace HTTP protokolu pro transport a XML formátu pro přenos dat [25].
37
4.Remoting na J2ME klientu Webová služba pro přenos, jak bylo zmíněno výše, používá nejčastěji protokol HTTP. Tento protokol je úzce spjat s Internetem (webem), odtud název webové služby. Pro přenášená data se užívá tzv. SOAP (Simple Object Acces Protocol). Je to protokol založený na XML a umožňuje přenášet strukturovaná data, jako objekty a seznamy mezi webovou službou a jejím konzumentem. Specifikace, které se týkají SOAPu a webových služeb, jsou spravovány konsorciem W3C15. Popis webové služby, tedy jaké nabízí možnosti a funkce, je dostupný v tzv. WSDL dokumentu (Web Service Description Language). Jedná se o metadata webové služby vyjádřená v unifikovaném formátu. Webová služba je v tomto XML dokumentu popsána z pohledu nabízených metod, jejich parametrů, návratových hodnot a XML schématu pro přenášené objekty.
4.3.2 SOAP zpráva Kompletní specifikaci SOAP protokolu lze nalézt např. na http://www.w3.org/TR/soap12part1/#soapenv, nejdůležitější části zprávy jsou uvedeny na následující příkladu zachyceném při komunikaci v rámci modelové aplikace: <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://axis2.server.blog.berger.cz"> <soap:Header /> <soap:Body> userpassword 15 http://www.w3c.org
38
4.Remoting na J2ME klientu Celá zpráva je zapouzdřena v elementu obálky – soap:Envelope, který obsahuje veškerá přenášená data. Uvnitř tohoto rodičovského prvku se nachází jeden nebo dva elementy s informacemi. Nepovinný je prvek soap:Header který může obsahovat hlavičky, vztahující se ke zprávě. Nemusí být uveden vůbec, případně může být prázdný. Po hlavičce následuje tělo zprávy v elementu soap:Body. Uvnitř tohoto elementu se nacházejí samotná data, zde objekt s informacemi vztahující se k přihlašování uživatele, kdy se na server zasílá uživatelské jméno a heslo.
4.3.3 Webové služby na J2ME JSR 172 definuje tzv. Web Services API (WSA). Bylo navrženo pro obě J2ME konfigurace (jak CLDC verze 1.0 a 1.1, tak i pro CDC). Celé API je založeno na podmnožině Java API pro XML-RPC (JAX-RPC 1.1). Zahrnuje i některé třídy z RMI a pro parsování XML zpráv je použita podmnožina Simple API pro XML verze 2 (SAX2). ([26]) Schéma fungování webových služeb u mobilních zařízení je uvedeno na následujícím obrázku:
Obrázek 4: Schéma použití webových služeb na J2ME (převzato z [26]) J2ME aplikace využívá JSR 172 API, konkrétně vygenerovaný stub. Tento zástupný objekt poskytuje rozhraní pro volání serveru a deleguje svá volání na implementaci webových služeb, které poskytuje mobilní zařízení. Komunikace pak probíhá skrze bezdrátovou síť a Internet k poskytovateli služby (Service producer na obrázku).
39
4.Remoting na J2ME klientu
4.3.4 JSR 172 API subset S ohledem na omezení cílových zařízení (konzumentů webových služeb) má využití JSR 172 některá omezení a specifika, kterým je přizpůsobeno i API (kompletní přehled lze nalézt na [26], v sekci The JSR 172 JAX-RPC Subset API) : •
Splňuje profil WS-I Basic
•
Podpora pouze protokolu SOAP 1.1.
•
Jako transport lze použít libovolný protokol specifikovaný pro SOAP 1.1.
•
Podpora všech primitivních datových typů (pro CLDC 1.0 se float a double mapují jako řetězce).
•
Nepodporuje SOAP zprávy s přílohami.
•
Mobilní zařízení nemůže vytvořit tzv. endpoint, a nemůže tak sloužit jako server.
4.3.5 Použití JSR 172 Pro využití
JSR 172 API je nezbytné, aby jej nabízelo samotné zařízení. Na rozdíl
od ostatních metod (jako je třeba Burlap), se jedná o volitelný balíček API, který musí být přímo součástí JVM. Obsahuje totiž balíčky java a javax , do kterých aplikace nemůže vytvářet třídy a ty musí být zakomponovány přímo ve virtuálním stroji. Pokud aplikace obsahuje vlastní třídy v těchto balíčcích, tak i přesto, že jsou tyto třídy na aplikační classpath, dochází k vyjímce java.lang.NoClassDefFoundError: javax/class_name: Cannot create class in system package. Jedná se o bezpečnostní mechanismus celé platformy, který je aplikován ve všech verzích Javy (J2SE, J2EE i J2ME). Tato skutečnost poněkud limituje využití JSR 172, protože ne všechna zařízení mají tento balíček k dispozici. Objevuje se zejména u výkonnějších zařízení. Typický postup při vytváření klienta je dle [26] následující: 1. Vygenerování zástupné (stub) třídy z WSDL dokumentu, který popisuje webovou službu. 2. Instanciování zástupné třídy a nastavení jejích atributů (např. URL služby). 3. Volání metod na zástupné třídě. 40
4.Remoting na J2ME klientu Generování stubu K vygenerování zástupné třídy (dále jen stub) lze použít nástroj, který je zabudován do Sun Java Wirelles Toolkit for CLDC (http://java.sun.com/products/sjwtoolkit/) (dále jen WTK). Postup je velice snadný. V hlavním menu WTK je nutné založit nový projekt mobilní aplikace. Pro tuto aplikaci stačí doplnit volitelná API. Buď specifikováním cílové platformy MSA (Mobile Service Architecture), případně lze ručně specifikovat balíčky, které budou dostupné. Po založení projektu lze z menu Project – Stub generator … vyvolat nástroj pro vygenerování stubu z WSDL dokumentu. Adresu WSDL dokumentu lze zadat přímo jako URL serveru odkazující na WSDL, případně lze vybrat soubor na disku.
Obrázek 5: Generátor JSR 172 stub (screen-shot aplikace) Vygenerovaný projekt, resp. třídy lze nalézt ve WTK workspace, které se standardně nachází v adresáři s uživatelským profilem (podsložka s uživatelským jménem v C:\Users pro Windows Vista, C:\Documents and settings\ pro Windows XP/2000, /home pro Unixové systémy jako je Linux). Zde se nachází adresář j2mewtk se standardní strukturou. Při vývoji vzorové aplikace byl použit Axis2 framework (viz. Podkapitola 6.3 týkající se serverové části). Ten na specifikovaném URL s webovou službou nabízí její WSDL dokument.
41
4.Remoting na J2ME klientu Při dodržení omezení, která vyplývají ze specifikací webových služeb pro mobilní zařízení, jako je např. absence a nemožnost použití xsd:date pro přenos data a času, je kombinace Axis2 a JSR172 ve vzorové aplikaci použitelná. Podmínkou je pouze použití formátu dat webové
určuje hlavně formát SOAP zpráv a způsob přenášení dat a je jako jediné povolené ve specifikacích JSR 172. Dokument WSDL, vygenerovaný Axis2 runtimem přímo z třídy představující službu, lze použít pro stub generátor. Při vytváření vzorové aplikace ovšem docházelo k chybám. Bylo nutné WSDL upravit tak, aby zachovalo formát přenášených dat beze změny a přitom bylo možné jej zpracovat stub generátorem. Konkrétně se jedná o úsek XML schématu, který popisuje vyjímku BloggerException a její dědění od třídy Exception, tak, jak ji generuje Axis2 framework. <xs:complexType name="Exception"> <xs:sequence> <xs:element minOccurs="0" name="Exception" nillable="true" type="xs:anyType"/> <xs:element name="BloggerException"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="BloggerException" nillable="true" type="ax21:BloggerException"/> …
Základní vyjímka java.lang..Exception, od které dědí všechny vyjímky v Javě, má několik konstruktorů a umožňuje instanciování na základě jiné vyjímky (resp. implementace rozhraní Throwable) nebo zprávy ve formě řetězce. Tuto skutečnost zachycuje úsek schématu definující komplexní typ Exception, která může obsahovat další elementy libovolného typu. To nepředstavuje problém na J2SE prostředí, kde je možné instanciovat prakticky libovolnou třídu na základě přijatých dat. Na J2ME je ovšem vyjímku možné vytvořit pouze na základě řetězcové zprávy a stub generátor předem musí mít určen typ. S touto skutečností souvisí i parametr message. Zmíněný atribut by byl v třídě BloggerException zděděn od třídy Exception. Pro použití J2ME klienta je ovšem nutné tento atribut předefinovat v třídě BloggerException, aby byl zachycen v příslušném úseku XML schématu. WTK stub generátor jinak nesprávně reprezentuje WSDL a zpráva vyjímky není ze SOAP dokumentu vůbec přečtena. Pokud nedojde při generování stub třídy k žádným chybám, jsou do zdrojového adresáře projektu vytvořeny příslušné balíčky a třídy, které odpovídají WSDL dokumentu. Generátor vytvoří rozhraní, které se jmenuje stejně jako webová služba, a implementaci tohoto rozhraní se suffixem _Stub. Dále je nagenerován datový model, který je vytvořen na základě elementů ve WSDL. Vše ve zdrojovém tvaru a je tedy nutné provést kompilaci.
43
4.Remoting na J2ME klientu Použití stubu Vygenerovaný stub je běžná třída a stejně tak se s ní proto zachází. Stub vygenerovaný z WTK bere adresu serveru a její endpoint (koncový bod) přímo z WSDL dokumentu. Ale webová služba není vždy generována přímo z produkčního systému, který je dostupný z Internetu, a proto lze koncové URL změnit. K tomuto účelu není možné využít přímo rozhraní webové služby, ale je nutné pracovat přímo s objektem stubu. Toho lze docílit pomocí přetypování. BloggerFacadeAxisProxyPortType proxy = null; //interface ... proxy = new BloggerFacadeAxisProxyPortType_Stub(); ((BloggerFacadeAxisProxyPortType_Stub)proxy)._setProperty( Stub.ENDPOINT_ADDRESS_PROPERTY, serverUrl);
Přes proměnnou proxy, která reprezentuje webovou službu, pak jsou dostupné jednotlivé metody, tak jak byly popsány ve WSDL. Volání metod se deleguje na JSR 172 runtime a vygenerované třídy, které komunikují se serverem. Rozhraní BloggerFacadeAxisProxyPortType, tedy rozhraní služby, dědí od java.rmi.Remote což je rozhraní, které označuje třídu určenou pro volání i ze vzdálené JVM. Všechny metody, které
komunikují mezi lokální a vzdálenou JVM musí mít v hlavičce uvedeno, že mohou
generovat java.rmi.RemoteException.
4.3.6 Obsluha vyjímek Jednotlivé metody na stubu (resp. rozhraní služby, které stub implementuje) mohou deklarovat aplikační vyjímky (převzaté ze serverových metod a popsané ve WSDL) , v tomto případě BloggerException. Kromě aplikační vyjímky (která je nepovinná) musí každá metoda rozhraní webové služby deklarovat i vyjímku java.rmi.RemoteException, která je generována v případě chyby v komunikaci.
44
4.Remoting na J2ME klientu
4.3.7 Zabezpečení Stejně jako předcházející metody, využívá i JSR 172 pro transport HTTP protokol. Je tedy možné jej zabezpečit pomocí HTTPS. K těmto účelům stačí změnit pouze URL serveru, resp. použitý protokol.
4.4 kSOAP2 Obdobně jako JSR 172, je možné knihovny kSOAP2 (použitá verze 2.1.2) použít ke spolupráci s webovými službami, které využívají SOAP protokol pro zapouzdření přenášených dat. Oproti JSR 172 je ale dostupná všude, protože se jedná o uživatelskou knihovnu, resp. balíčky. Je to knihovna
nízkoúrovňová, v Java kódu pracuje přímo s XML elementy a jejich
hodnotami, atributy a potomky.
4.4.1 Použití kSOAP2 Při použití kSOAP2 knihovny pro zpracování webových služeb je nutné vyřešit v podstatě veškeré serializace a deserializace programově, na rozdíl od užití JSR 172, kdy je celý kód zajišťující komunikaci generován. Při tvorbě vzorové aplikace a psaní následujícího textu bylo čerpáno z několika málo existujících zdrojů, které se zabývají knihovnou kSOAP2 ([27], [28], [29]) a API dokumentace [30]. Následující postup užití knihovny bude demonstrován na metodě pro získávání všech příspěvků, tedy metodě getPosts(Person, Date) , která je implementována ve třídě cz.berger.blog.client.KSoapBloggerFacadeImpl. Opakující se postupy při užití knihovny kSOAP2 pochází z pomocné abstraktní třídy cz.berger.blog.client.ksoap2.AbstractKSoapClient, která zapouzdřuje opakující se operace spojené s touto knihovnou.
45
4.Remoting na J2ME klientu Následující postup zachycuje posílání jak primitiv, tak i komplexních objektů, které bylo nutné v podstatě celé empiricky dohledat a vyzkoušet. Jako server je zde opět použit Axis2 a jeho generovaný WSDL dokument. Názvy elementů a jmenných prostorů v SOAP zprávách proto odpovídají konvencím tohoto frameworku. Použití kSOAP2 knihovny bylo zapouzdřeno pro co nejjednodušší použití do metody call(String) na třídě AbstractKSoapClient. S využitím návrhového vzoru „template method“16 umožňuje instanciování této třídy měnit části algoritmu u konkrétního objektu. Lze překrýt metodu registerClassMapping() pro nastavení vazeb mezi SOAP elementy a třídami a metodu writeRequest() pro zapsání požadavku na server. Celá metoda call na AbstractKSoapClient obsahuje tyto kroky, které představují model použití KSoap2 knihovny: 1. Vytvoření obálky SoapSerializationEnvelope a určení verze SOAP protokolu. SoapSerializationEnvelope envelope; String url = “BlogServer:8080/BlogServer/services/BloggerFacadeAxisProxy.Blogg erFacadeAxisProxyHttpSoap11Endpoint/“; ... envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
2. Nepovinné zaregistrování mapování objektů na SOAP elementy, které může být překryto (popsáno dále). this.registerClassMapping();
3. Zapsání požadavku na server do obálky. this.writeRequest();
4. Vytvoření transportu pro server specifikovaný url atributem. Pomocí dědění od třídy org.ksoap2.transport.Transport lze vytvořit i jiný transportní protokol než HTTP. Transport transport = new HttpTransport(url);
16 http://objekty.vse.cz/Objekty/Vzory-Template
46
4.Remoting na J2ME klientu 5. Zavolání metody soapAction na serveru a předání obálky. transport.call(soapAction, envelope);
6. Přečtení a vrácení odpovědi z obálky. return envelope.getResponse();
Povinné je pouze překrytí metody writeRequest z kroku 3, ve kterém se do obálky zapouzdřující volání zapíší parametry metody na serveru. Odchozí ukázková SOAP zpráva pro metodu getPosts, tak jak je generována pomocí kSOAP2, je následující: TESTING PERSON1abCdeF_11233829674410
Pro vygenerování této zprávy je tedy překryta metoda AbstractKSoapClient.writeRequest , v rámci které je dostupná serializační obálka (envelope) a uživatelská data (objekty person, fromDate), kompletní kód viz. třída cz.berger.blog.client.facade.KSoapBloggerFacadeImpl. 47
4.Remoting na J2ME klientu Nejprve je vytvořen objekt odchozího elementu n0:getPost. V tomto elementu, který má odpovídající jmenný prostor (n0 – http://axis2.server.blog.berger.cz), je zapouzdřeno volání metody serveru. K tomu účelu se instanciuje třída org.ksoap2.serialization.SoapObject. SoapObject getPosts = new SoapObject("http://axis2.server.blog.berger.cz", "getPosts");
Do tohoto objektu se pak zapíší jednotlivé parametry volání, které budou reprezentovány jako výše uvedená část XML. getPosts.addProperty("person", new KSoapPerson(person)); getPosts.addProperty("fromDate", new Long(fromDate.getTime()));
Primitivní datové typy (resp. jejich objektové wrappery) nepotřebují žádné speciální úpravy a kSOAP je zpracuje. To je příklad zde uvedené fromDate, typu long, nebo např. řetězců. V případě komplexních objektů (zde objekt person) je nutno serializaci a deserializaci řešit programově (viz. následující podkapitola). K dokončení požadavku na server se celý odchozí objekt s požadavkem zapíše do obálky. envelope.setOutputSoapObject(getPosts);
Takto překrytá metoda writeRequest() je pak zavolána uvnitř metody call() a klientu se vrátí objekt odpovědi převzatý z obálky (viz. bod 6 popisu metody call).
4.4.2 Serializace a deserializace komplexních objektů Jak již bylo zmíněno, primitivní datové typy lze serializovat přímo. V případě, že se jedná o neznámý primitivní datový typ, nebo nepodporovaný kSOAP2 knihovnou, je možné použít třídu org.ksoap2.serialization.SoapPrimitive. Dle API dokumentace lze s její pomocí serializovat např. float hodnoty, případně se do této třídy převedou přijaté nekomplexní datové typy nerozpoznané parserem, resp. jeho class-map.
48
4.Remoting na J2ME klientu Komplexní objekty se pak serializují nebo deserializují v závislosti na použití knihovny. První přístup
používá úpravu
na doménových
objektů
tak, že implementují
rozhraní
org.ksoap2.serialization.KvmSerializable a registrují se do obálky a parseru. To zajišťuje automatický převod mezi SOAP zprávou a Java objekty. Druhý přístup spočívá ve využívání pouze org.ksoap2.serialization.SoapObject, do kterého se převádí jak doménové objekty, tak i SOAP zprávy. Oba přístupy je možné kombinovat. Užití rozhraní KvmSerializable Rozhraní org.ksoap2.serialization.KvmSerializable poskytuje „reflexi“ v prostředí CLDC. Objekty, které implementují toto rozhraní, poskytují sadu metod, jichž využívá parser SOAP zpráv pro vytvoření objektů ze zprávy a naopak. V modelovém příkladu se to týká balíčku cz.berger.blog.client.ksoap2, například třídy KsoapPost, KsoapPerson apod. Tyto třídy implementují rozhraní KvmSerializable a zároveň v sobě zapouzdřují i originální doménové objekty. KvmSerializable
Rozhraní KvmSerializable předepisuje několik metod. Metoda setProperty(int, Object) je volána parserem a do objektu předává hodnotu převzatou z parsovaného elementu, která odpovídá číselnému indexu. Způsob „reflexe“ knihovny kSOAP2 je založen na číselném označení pořadí atributů objektu, na které se odvolává parser při serializaci a deserializaci. U modelové třídy KSoapPost je tak na indexu 0 titulek příspěvku, na indexu 1 čas vytvoření atd. V následujícím kódu je uvedeno zpracování indexu 0 ve výše zmíněné třídě, které do zapouzdřeného objektu post nastaví titulek z parserem předaného parametru value. switch (index) { case 0: post.setCaption(value.toString()); break;
49
4.Remoting na J2ME klientu S
pořadím
atributů
pracují
všechny
metody
rozhraní
KvmSerializable.
Metoda
getProperty(int) vrací atribut (objekt), který odpovídá danému číselnému indexu. Metoda getPropertyInfo(int, Hashtable, PropertyInfo) poskytuje parseru informace o objektu na daném indexu. Její třetí parametr je instance třídy org.ksoap2.serialization.PropertyInfo, kterým se parseru specifikuje jméno elementu (atribut name) v SOAP zprávě a jeho typ (atribut type), aby byl správně rozpoznán a převeden. switch (index) { case 0: info.name = "caption"; info.type = PropertyInfo.STRING_CLASS; break;
Atribut type je obecný objekt, buď jedna z konstant na třídě PropertyInfo, případně třída která implementuje rozhraní KvmSerializable. Mapování elementů na třídy
K tomu, aby parser dokázal zpracovat komplexní objekty s využitím KvmSerializable, je nutné na serializační obálce (envelope) registrovat elementy, jmenné prostory a odpovídající třídy. K registraci slouží metoda obálky addMapping(String mappingNs, String mappingName, Class mappingClazz). Parametr mappingNs udává jmenný prostor elementu, mappingName jeho jméno a mappingClazz pak třídu implementující rozhraní KvmSerializable, do které se odpovidající element zpracuje (při deserializaci), nebo ze které se vytvoří (při serializaci). Ve třídě z modelové aplikace (AbstractKSoapClient) je metoda addClassMap delegována právě na envelope.addMapping. Toto mapování tříd se používá pro SOAP elementy, které nejsou přímým potomkem těla příchozí zprávy a jsou zapouzdřeny uvnitř jiného serializovaného objektu. Pro mapování elementu, který je přímým potomkem soap:Body, je nutné provést ještě přidání tzv. šablony (template) pro parser. Šablona je element a přímý potomek soap:Body.
50
4.Remoting na J2ME klientu Element, který slouží jako šablona (template), je SoapObject. Má svoje jméno a jmenný prostor (templateName a templateNs). Pod šablonu je pak nutné přidat mapování objektu, který je v šabloně obsažen. Do šablony se registruje jméno elementu a třída (mappingName a mappingClazz) opět s využitím PropertyInfo objektu. V modelovém příkladu je tato metoda implementována ve třídě AbstractKSoapClient, pod jménem addClassTemplateAndMap (String templateName, String templateNs, String mappintName, String mappingNs, Class mappingClazz). SoapObject template = new SoapObject(templateNs, templateName); PropertyInfo ret = new PropertyInfo(); ret.name = mappingName; ret.type = mappingClazz; template.addProperty(ret,"");
Tím se do šablony registruje její obsah. Šablonu je dále nutné přidat do serializační obálky a obdobným způsobem jako v případě mapování bez šablony registrovat obsah šablony parseru. envelope.addTemplate(template); envelope.addMapping(mappingNs,mappingName, mappingClazz);
Například pro registraci následující SOAP zprávy do parseru: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns:addPostResponse xmlns:ns="http://axis2.server.blog.berger.cz"> <ns:return xmlns:ax21="http://model.blog.berger.cz/xsd" xmlns:ax24="http://axis2.server.blog.berger.cz/xsd" type="cz.berger.blog.server.axis2.AxisPost"> Caption12204296437753
51
4.Remoting na J2ME klientu Lorem ipsum ...
se zavolá mapování následovně: addClassTemplateAndMap("addPostResponse","http://axis2.server.blog.berg er.cz", "return", "http://axis2.server.blog.berger.cz", KSoapPost.class);
Oba elementy mají stejný jmenný prostor a výsledkem je třída příspěvku (Post, resp. jeho KSoap2 wrapper). Tento přístup s mapováním šablony je obdobný jako při vytváření požadavku na server a nastavení odchozího SOAP objektu obálky pomocí envelope.setOutputSoapObject(so). Mapování kolekce
Při mapování kolekcí není možné použití šablony. Jedná se o případ, kdy příchozí zpráva obsahuje kolekci objektů (příklad pochází z metody getPosts(Person, Date) na třídě KsoapBloggerFacadeImpl). Ke zpracování příchozí kolekce do instance třídy Vector je nutné použít namapování bez šablony s využitím speciálního vektoru (např.
potomka
cz.berger.blog.client.ksoap2.AbstractVectorResponse), kterému se překryjí metody vracející typ prvku v poli a jméno elementů s prvky. Namapování vektoru s odpovědí je pak následující: addClassMap("getPostsResponse", "http://axis2.server.blog.berger.cz", PostsResponseVector.class); addClassMap("return", "http://axis2.server.blog.berger.cz", KSoapPost.class); addClassMap("comments", "http://axis2.server.blog.berger.cz", KsoapComment.class);
52
4.Remoting na J2ME klientu Element getPostsResponse je rodičovský element kolekce, představované vektorem PostResponseVector, potomky tohoto prvku jsou elementy return, které obsahují jednotlivé příspěvky (KSoapPost). V rámci těchto příspěvků jsou ještě zahrnuty komentáře (KSoapComment). Způsob mapování vrácených kolekcí je implementován podle [29], konkrétně pak z jediného dostupného
příkladu,
který
zpracovává
kolekci
řetězců
se
jmény
stadionů
(http://ksoap2.wiki.sourceforge.net/Stadiums+at+the+World+Cup+Example). Převod do SoapObject Přístup s využitím rozhraní KvmSerializable a registrací class map přímo do parseru zprávy nemusí být vždy vhodný. V případě jednodušších zpráv lze použít i přístup, kdy se všechny příchozí a odchozí objekty převádějí na SoapObject. Do těchto objektů také parser převádí všechny komplexní XML elementy, u kterých není nastavena classmap pro převod do specifické implementace KvmSerializable. [30] SoapObject toto rozhraní implementuje a všechny elementy v SOAP zprávě jsou uloženy v tomto objektu. Kromě metod předepsaných rozhraním KvmSerializable, jsou v této třídě dostupné i další metody. Dvě nejpodstatnější se používají pro přidávání a zpětné získávání informací (objektů), které SoapObject zapouzdřuje do XML elementů. K vytvoření SoapObject je nutné specifikovat jeho jméno (jméno elementu) a jmenný prostor elementu. Metoda addProperty, přetížená pro dvě různá volání, slouží k přidání hodnoty do objektu. Pomocí ní lze vytvářet jednotlivé podelementy daného SOAP elementu, které představují atributy (data) nesená zprávou. V jednodušším volání se pouze předává jméno elementu a jeho hodnota. Jako
příklad
lze
uvést
část
kódu
ze
vzorové
aplikace,
třídy
cz.berger.blog.client.ksoap2.BasicKSoapSerializer, metody getSoapFromPerson(Person). SoapObject res = new SoapObject("http://axis2.server.blog.berger.cz", "person"); res.addProperty("fullName", person.getFullName());
53
4.Remoting na J2ME klientu Obdobným způsobem lze vytvářet libovolné hiearchie objektů, kde jednotlivé vlastnosti (property), přidáváné pomocí addProperty mohou být jak primitiva, tak i komplexní objekty reprezentované buď SoapObject nebo implementací rozhraní KvmSerializable. Jak napovídá název metody addProperty, v případě, že se přidává další vlastnost se stejným názvem, který byl již jednou použit, vede tato metoda k vytvoření více stejných elementů seznamu. Pro získání informací ze SoapObject, např. po naparsování příchozí SOAP zprávy, lze využít metodu getProperty(String), která vrací hodnotu (vlastnost) s daným názvem, předaným jako parametr. Typ návratové hodnoty je pak buď SoapPrimitive nebo SoapObject v závislosti na elementu, ze kterého byla vlastnost naparsována. SoapObject so; SoapPrimitive pr = (SoapPrimitive) so.getProperty("fullName");
Tento přístup získání hodnoty ovšem nelze použít v případě, že daná vlastnost je pole. Tedy, že se vyskytuje více elementů uvnitř objektu, které mají stejný název. V tom případě parser zachová pouze poslední v pořadí. Pro zpracování polí a seznamů je tak nezbytné využití KvmSerializable, které element s daným jménem ukládá do Vectoru nebo pole. Tak jak je tomu v třídě cz.berger.blog.client.ksoap2.KSoapPost a vlastnosti „comment“ (komentáře k příspěvku).
4.5 RMI (JSR 66) Java řešení pro vzdálené volání metod – Remote Method Invocation (RMI) – umožňuje psát distribuované aplikace. Poskytuje model pro komunikaci mezi JVM s využitím objektů, které například obalují existující API a poskytují vzdálený přístup pro klienty. [31], [32] RMI využívá distribuovaný systém založený na objektech. Tím izoluje klienta (uživatele) služby od serveru a tedy implementace. Vývoj distribuované aplikace s využitím RMI se dle [32] nechá shrnout do několika základních kroků :
54
4.Remoting na J2ME klientu 1. Definování vzdáleného rozhraní – vzdálené rozhraní je běžné Java rozhraní (interface), které dědí od java.rmi.Remote a jehož metody přístupné pro klienta musí povinně v hlavičce deklarovat možnost vyhození java.rmi.RemoteException. Tato výjimka zapouzdřuje chyby, ke kterým může docházet při přenosu. 2. Vytvoření implementace rozhraní – implementace samotné logiky, kterou rozhraní představuje. 3. Vytvoření serveru – představuje instanciování vzdáleného rozhraní a jeho provázání s RMI registrem pomocí jména. RMI registr je služba, která zprostředkovává přístup ke vzdáleným rozhraním. 4. Vytvoření klienta – spočívá v nalezení RMI registru a požádání o objekt s daným jménem, který reprezentuje vzdálené rozhraní. Tento objekt po přetypování slouží ke vzdálenému volání.
4.5.1 RMI na J2ME Na prostředí J2ME je RMI dostupné v podobě volitelného balíčku pro konfiguraci CDC. Specifikace je podrobněji popsána v příslušném JSR 66 a představuje podmnožinu RMI z J2SE 1.3 API.17 Dle API a specifikace jsou podporovány základní prvky z J2SE 1.3. Zde následuje přehled některých základních (vybráno z API, [33]): •
Plná sémantika volání včetně dynamického class loadingu. Pokud na klientu není dostupná třída objektu, který byl např. vrácen vzdálenou metodou, RMI implementace použije dynamické nahrání a zpřístupní definici třídy přijímající straně.
•
Distribuovaný garbage collector mechanismus pro uvolňování paměti v případě, že neexistuje lokální ani vzdálený ukazatel na objekt.
•
Podpora RMI registru a jejich hledání s využitím java.rmi.registry.Registry, java.rmi.registry.LocateRegistry a java.rmi.Naming.
•
RMI komunikační protokol pro zajištění komunikace přes síť.
Vyexportování vzdálených objektů s využitím java.rmi.server.UnicastRemoteObject API . Z UnicastRemoteObject dědí implementace vzdáleného rozhraní na serveru.
Zahrnuty naopak nejsou některé další vlastnosti, které J2SE 1.3 nabízí, jako je využití HTTP proxy a tunelování skrze firewally, podpora pro stub/skeleton protokol z JDK 1.1 nebo kompilátor pro generování stub a skeleton tříd. Od verze Javy 1.5 (5.0) došlo k zásadnímu přepracování RMI řešení zejména při tvorbě serveru a řešení komunikace s využitím zástupných tříd (proxy). Tato práce se ovšem zabývá řešením na J2ME, kde je nutné použít starší specifikace a přístupy k řešení, zejména u serverové části. Je tedy nutné použít rmic kompilátor a generovat stub a skeleton třídy pro implementaci vzdáleného rozhraní. Vytvoření serveru, který dokáže komunikovat s CDC klientem prostřednictvím RMI, je zpracováno v části zabývající se modelovou aplikací.
4.5.2 Použití RMI Použití RMI je v porovnání s ostatními metodami relativně snadné. Klientská aplikace musí pouze získat referenci na objekt, který je dostupný z RMI registru na serveru. Na Java ME je postup řešení obdobný jako v případě [32], sekce Develop client, ovšem třídy dostupné z RMI volitelného balíčku jsou odlišné. Prvním krokem je zavedení security manageru. To umožní načíst klientovi třídy ze serveru pokud nejsou dostupné na jeho classpath. Zároveň je nutné spuštění klienta s právy, které umožní připojit se na konkrétní server (parametr -Djava.security.policy s odkazem na soubor práv, přidělených aplikaci, viz [32], Runníng the application. Nastavení práv je na J2ME simulátoru shodné jako u J2SE aplikace). if (System.getSecurityManager() == null)
Poté je s využitím třídy java.rmi.registry.LocateRegistry nalezen příslušný RMI server. Klient se tak pokusí připojit na server a definovaný port, na kterém běží registr.
56
4.Remoting na J2ME klientu Registry registry = LocateRegistry.getRegistry(RMI_SERVER,RMI_PORT);
Poté stačí z registru získat referenci na příslušný objekt a přetypovat na rozhraní, které představuje vzdálenou službu. RmiBloggerFacade facade; ... facade = (RmiBloggerFacade) registry.lookup("BloggerFacade");
Toto rozhraní musí odpovídat RMI konvencím, jak je uvedeno výše v kroku 1. při tvorbě RMI aplikace. Tedy dědí z java.rmi.Remote a metody povinně deklarují, že mohou generovat java.rmi.RemoteException. Metoda getRegistry na třídě LocateRegistry může generovat vyjímku RemoteException v případě chyby při komunikaci s registrem, metoda lookup na Registry objektu pak kromě této navíc i java.rmi.NotBoundException pro případ, že jméno požadované z registru (zde BloggerFacade) nemá přiřazen žádný objekt, který by server mohl vrátit.
4.5.3 RMI class loader Dle API a [33] je i v RMI volitelném balíčku dostupný dynamický class loading. V případě, že v průběhu komunikace přes RMI dojde k požadavku instanciování třídy, která není dostupná na klientově classpath, je tato třída, resp. její definice stažena ze serveru. K tomu samozřejmě musí mí aplikace povolení v policy souboru. Pokud je server a klient na stejném počítači (v případě ladění) je nutné povolit přístup k souborům na souborovém systému. Jedná-li se o komunkaci prostřednictvím sítě je možné zpřístupnit třídy např. prostřednictvím HTTP serveru a spuštěnému klientu nastavit systémovou proměnnou java.rmi.server.codebase. Tímto nastavením klient získá adresu odkud stáhne požadované třídy. Verze class souborů na serveru musí odpovídat prostředí do kterého je nahrávána. Tedy pro použití na CDC konfiguraci musí být třídy kompilovány s kompatibilitou pro prostředí Javy 1.3, jinak není možné třídy na klientu použít.
57
4.Remoting na J2ME klientu
4.5.4 Ošetření vyjímek Propagování aplikačních vyjímek je řešeno samotným RMI mechanismem. Každá metoda na vzdáleném rozhraní navíc povinně deklaruje RemoteException, ke které dochází v případě chyb při komunikaci se serverem (chybná serializace apod.).
4.5.5 Zabezpečení K zabezpečení RMI komunikace je možné od verze Javy 1.2 užít SSL. K využití komunikace prostřednictvím zabezpečených socketů postačuje implementovat a použít vlastní RMI Socket factory, jak je popsáno v Using a custom RMI socket factory z [34]. Konkrétní implementace a řešení použité v modelové aplikaci pochází ze sekce JSSE code examples
([34]).
Konkrétně
se
jedná
o
třídy
RMISSLClientSocketFactory
a
RMISSLServerSocketFactory. V modelové aplikaci jsou tyto třídy převzaty tak, jak dovoluje licence. Klientská třída beze změny, serverová s drobnou úpravou, která umožňuje v konstruktoru definovat úložiště klíčů a heslo k němu, pro získání certifikátu k šifrování komunikace. Obě se nacházejí v balíčku cz.berger.blog.server.rmi na serveru a jsou použity v konfiguraci Spring serveru (viz. následující kapitola). Kromě toho je klientská cz.berger.blog.server.rmi.RMISSLClientSocketFactory i v CDC prostředí. Její implementace a umístění v balíčku je shodná jako na serveru. Pokud by na klientu tato třída nebyla, byl by použit RMI class loading a byla by stažena ze serverové RMI codebase. I to je možné jen za předpokladu, že je tato třída kompilována pro verzi Javy 1.3.
4.6 REST architektura REST - Representational State Transfer je architektonický koncept pro řešení distribuované architektury [35]. V páté kapitole svojí disertační práce [36] tento přístup popsal Roy Fielding, mj. jeden z autorů HTTP protokolu18. Ostatní zde zmíněné metody remotingu užívají tzv RPC model – Remote Procedure Call, tedy vzdálené volání procedur a metod. REST architektura je postavena nad jiným přístupem ke komunikaci. Definuje několik základních pojmů [35],[36]: 18 http://en.wikipedia.org/wiki/Roy_Fielding
58
4.Remoting na J2ME klientu •
Zdroj (resource), je abstrakce nad stavem a chováním aplikace. Je to klíčový prvek architektury. V modelové aplikaci je zdrojem např. příspěvek v systému, seznam příspěvků nebo uživatel.
•
Každý zdroj má unikátní identifikátor, jako např. URL adresu.
•
Nad každým zdrojem jsou definovány max. 4 operace v podobě tzv. CRUD aktivit (Create – vytvoření, Read – čtení, Update - změna, Delete – smazání). Ty zapouzdřují to, co lze se zdrojem provést.
•
Každý zdroj může mít různé reprezentace. Reprezentace je vyjádření zdroje v nějakém formátu, jako je XML, HTML, JSON, SVG grafika, nebo JPG obrázek. Zvolená reprezentace může záviset např. na klientu - pokud přistupuje desktopový klient, je zdroj reprezentován jako XML, pokud mobilní klient, je použit méně náročný JSON apod.
Častým řešením REST architektury je použití protokolu HTTP a jeho metod , které poskytuje. Lze tak na URL, které představuje nějaký zdroj zasílat HTTP požadavky různými metodami a tak provádět operace. Užívá se např. následující navázání: REST operace
HTTP metoda
Create
POST
Read
GET
Update
PUT, POST
Delete
DELETE
Tabulka 1: Vazba REST operací na HTTP metody ([37], sekce RESTful example:the WWW) REST přístup k architektuře má své výhody i nevýhody. Některé z nich lze nalézt na [35]. Jeho časté řešení s využitím HTTP protokolu a různých reprezentací zdrojů jej dovoluje použít i na J2ME platformě. V modelové aplikaci je například na URL http://localhost:8080/BlogServer/rest/posts/ pomocí metody HTTP GET možné získat seznam příspěvků v JSON formátu. Metodou HTTP POST je pak na stejném URL možné přidat nový příspěvek, zaslaný v těle požadavku.
59
4.Remoting na J2ME klientu
4.6.1 J2ME REST klient Na platformě J2ME je možné pracovat s HTTP protokolem. V CLDC profilu MIDP i v CDC Foundation profilu je dostupný balíček javax.microedition.io a v něm factory třída Connector pomocí které lze získávat různé druhy spojení. Pro řešení REST klienta přes HTTP protokol jsou důležitá rozhraní HttpConnection a SocketConnection (resp. HttpsConnection a SecureConnection pro použití SSL). Nad instancí HttpConnection lze na příslušné URL provést požadavek typu POST například takto (proudy i spojení je samozřejmě po ukončení přenosu nutné uzavřít, zde je tato část vynechána): String data = “somedata“; byte[] buffer = new byte[1024]; ... HttpConnection httpConn = (HttpConnection) Connector.open(serverUrl); httpConn.setRequestMethod(HttpConnection.POST); httpConn.setRequestProperty("Content-length", ""+data.getBytes().length); output = httpConn.openOutputStream(); output.write(data.getBytes());
Voláním metody setRequestMethod se nastaví typ HTTP požadavku na POST. Pokud není tato metoda zavolána, je užita metoda GET. Kromě metod POST a GET poskytuje J2ME platforma prostředky ještě pro volání HEAD požadavku. Do vytvořeného spojení lze zapsat hlavičky pomocí setRequestProperty (HTTP metadata o spojení, jako např. velikost přenášených dat, identifikace klienta, ...). Po odeslání hlaviček lze otevřít výstupní proud a do něho zapsat data. Pro čtení odpovědi stačí na spojení otevřít vstupní proud a přečíst obdobně jako z jiného vstupního proudu. InputStream input
= httpConn.openInputStream();
input.read(buffer);
60
4.Remoting na J2ME klientu Jak bylo zmíněno výše, na J2ME jsou dostupné pouze HTTP metody GET, POST a HEAD. Ostatní typy metod jako je PUT, DELETE nebo méně známé OPTIONS či CONNECT podporovány nejsou. Absence metody PUT pro řešení J2ME REST klienta není až tak zásadní, lze ji zastoupit pomocí metody POST a počítat s tímto omezení již při návrhu serveru. Ovšem metoda DELETE musí být implementována na klientu pomocí soketového spojení a ručního vypsání kompletního HTTP požadavku do výstupního proudu. Například tak, jak je implementováno v modelové aplikaci, kde se předpokládán DELETE požadavek bez vracení odpovědi. (následující kód je převzat, konkretizován a sloučen z více metod modelové aplikace, kde je obecný pro libovolný server – třída HttpClient). Spojení je otevřeno obdobně jako pro HttpConnection, je použit pouze jiný protokol. String data
= “someData”;
String uri = "socket://localhost:8080/BlogServer/rest/posts/1"; socketConn = (SocketConnection) Connector.open(uri);
Nad výstupním proudem je vytvořen PrintStream pro zápis řádků a do něho jsou vypsány náležitosti pro HTTP požadavek. PrintStream out = new PrintStream(socketConn.openOutputStream()); out.println( "DELETE "+uri+" HTTP/1.1" );
out.println("Host:localhost:8080“); out.println(“Auth-user:1b4cdf2”); out.println("Content-length:"+data.length()); out.println(); //separate HTTP header from body out.println(data); out.flush(); out.close();
61
4.Remoting na J2ME klientu Čtení odpovědi je pak podobné jako v případě HttpConnection , otevřením vstupního proudu a čtením jednotlivých řádků. Ovšem v případě soketového spojení je nutné nejprve zpracovat hlavičku HTTP požadavku a poté tělo. Informace z hlavičky, jako je stavový kód odpovědi (200 - OK, 404 - nenalezeno apod.) je nutné parsovat ručně. V modelové aplikaci je situace zjednodušena a server pro metodu DELETE nevrací žádná data, i když klientská část k tomu je připravena. V modelové aplikaci je logika pro snažší zpracování HTTP požadavků všemi metodami GET,POST,DELETE zapouzdřena v třídě cz.berger.blog.client.http.HttpClient. Z této třídy pochází i ukázky zdrojového kódu. Tím je odstíněna logika aplikace od použití soketů či HTTP
4.6.2 Ošetření vyjímek V modelové aplikaci je pro přenos dat mezi klientem a serverem použit JSON formát, obdobně jako v řešení s Hessian protokolem. Příchozí řetězec, který je přečten ze vstupního proudu, může tedy obsahovat jak data, tak serializovanou vyjímku. Parser, který zpracovává JSON řetězec v aplikaci (třída cz.berger.blog.client.json.JsonSerializerMEImpl), tak kontroluje příchozí řetězec na přítomnost klíče specifikujícího vyjímku. Tato třída je sdílená metodami pro Hessian i REST komunikaci.
4.6.3 Zabezpečení Protože tato implementace staví na HTTP protokolem, je možné použít i její zabezpečenou variantu HTTPS, a to pouhou změnou protokolu v URL serveru. V případě použití soketového spojení (nezbytného pro vyvolání metody DELETE na serveru) pak URL začíná protokolem ssl:// místo socket:// .
62
5.Server pro J2ME klienty
5. Server pro J2ME klienty Pro řešení remotingu na serveru je použit servletový kontejner Apache Tomcat (http://tomcat.apache.org)
v
kombinaci
se
Spring
frameworkem
verze
2.5
(http://www.springsource.org/). K řešení webové služby je použit framework Axis2 (http://ws.apache.org/axis2/), navázaný na Springový IoC kontejner. Nastavení a spolupráce technologií vychází ve všech případech z dokumentací k jednotlivým projektům. Nejvíce pak z [38], kapitoly 17 – Remoting. Konfigurace Springu se nachází ve webové aplikaci, adresář WEB-INF, soubor spring-servlet.xml.
5.1 Nastaveni HTTPS na Apache Tomcat Pro zabezpečení komunikace s využitím HTTPS je nutné nakonfigurovat tento protokol v souboru TOMCAT_HOME/conf/server.xml v elementu Service, kde jsou ostatní konektory:
Soubor úložiště klíčů (zde berger_cert.bin, heslo do úložiště: heslo1234), lze vygenerovat buď přímo nástrojem keytool z Java SDK, nebo pohodlněji nástrojem Portecle (http://portecle.sourceforge.net). Při vytváření klíče v keystore musí být CN atribut nastaven na jméno serveru, pro testování na místním počítači hodnota localhost. To je nezbytné kvůli importu klíčů do simulátoru, kde musejí být svázány s konkrétním serverem.
5.2 Burlap a Hessian server S využitím frameworku Spring je vytvoření serveru pro protokoly fy Caucho záležitostí pouze vytvoření Springové komponenty (pro Hessian stačí nahradit ve jméně třídy slovo Burlap za Hessian a změnit jméno bean definující URL na které služba bude dostupná).
63
5.Server pro J2ME klienty <property name="service" ref="facade"/> <property name="serviceInterface" value="cz.berger.blog.model.BloggerFacade"/>