Extinderea Interoperabilitatii Aplicatiilor Software
ABSTRACT
Capitolul I. ARHITECTURA ENTERPRISE
I.1. Arhitectura Client – Server
I.2. Arhitectura Multi-Nivel Distribuita
I.3. Arhitectura bazată pe Servicii Web
I.4. Arhitectura orientată pe servicii (SOA)
I.4.1. Ce este SOA?
I.4.2. Cum este structurată o arhitectură SOA?
Capitolul II. SERVICII WEB
II.1. Ce este un serviciu web?
II.2. Arhitectura serviciilor Web
II.3. Cum funcționează serviciile Web?
II.4. Structura protocolului unui Web service
II.5. Caracteristici ale serviciilor Web
II.6. Beneficii ale utilizării servicilor web
Capitolul III. TEHNOLOGII PENTRU SERVICII WEB
III.1. Protocolul SOAP (Simple Object Access Protocol)
III.1.1. Structura mesajelor SOAP
III.1.2. Stiluri in comunicarea SOAP
III.1.3. Avantaje si dezavantaje ale protocolului SOAP
III.2. Descrierea serviciilor Web
III.2.1. Structura unui document WSDL
III.3. UDDI (Universal Description, Discovery and Integration)
III.3.1. API pentru programatorii UDDI
III.3.2. Beneficiile utilizării UDDI
III.3.3. Informațiile oferite de UDDI
Capitolul IV. FRAMEWORK-uri și TEHNOLOGII UTILIZATE
IV.1. Spring
IV.1.1. De ce este util principiul de Inversiune a Controlului?
IV.1.2. Ce este principiul de Invesiune a Controlului?
IV.2. Implementări ale IoC Spring container
IV.3. Bean Configuration
IV.4. Conectarea automată (automatic wiring).
IV.5. Spring Web Services
IV.5.1. Suportul Spring-WS pentru Client
IV.6. Suportul Spring pentru operațiile de serializare / deserializare Object/XML
IV.2. JiBX
Capitolul V. REALIZAREA PRACTICĂ A PROIECTULUI
V.1. Specificațiile funcționale
V.2. Arhitectura componentelor sistemului
V.3. Modelul de date
V.4. Clientul de Web Services
V.4.1.Configurarea container-ului IoC de la Spring
V.4.1.1.Configurarea bean – urilor
V.4.1.2. Suport Java pentru interacțiune cu container-ul IoC de la Spring
V.4.2. Scenarii de execuție
V4.2.1. Autentificare client.
V.4.2.2.Vizualizare conținut media disponibil pe una dintre locațiile afișate.
V.5. Server-ul de servicii Web
V.5.1. Crearea documentului WSDL de descriere a serviciului.
V.5.2. Conversia obiectelor Java din si în documente XML
V.5.3. Definirea Serviciului
V.5.4. Creearea punctului de acces al serviciului (Service Endpoint)
V.5.5. Configurarea Container-ului de Spring
V.5.6. Configurarea fisierului web.xml.
Concluzii
Bibliografie
Anexe
Anexa 1 : Clasa SpringFactoryBean
Anexa 2 : Exemplu fisier de conversie Java/XML
Anexa 3 : Fisierul WSDL
ABSTRACT
Lucrarea de față are ca și obiective principale cunoașterea și prezentarea avantajelor utilizării serviciilor web în dezvoltarea aplicațiilor software. Acest fapt va fi evidențiat și concretizat în prezenta lucrare prin aplicarea practică a principiilor de comunicare utilizând astfel de servicii pentru prelucrarea și obținerea dateler necesare unei aplicații grafice. În speță lucrarea de față se concentrează pe aspectele practice de realizare a unui client/server de servicii web și pe integrarea și aplicarea acestora la o aplicație grafică de sine stătătoare.
Și mai concret obiectivul lucrării de față se ocupă în special de a implementa o solutie particulara a comunicarii bazate pe servicii web care sa asigure suportul de comunicare dintre o aplicație desktop ca și client si un server ce furnizeză servicii web specializate pe monitorizariea și gestiunea unor locații de conținut media (video) și a conținutului acestora.
Nevoia de a face aplicațiile software disponibile oriunde în lumea internetului a devenit esențială. De asemenea, nevoia de interoperabilitate a aplicațiilor, adică abilitatea aplicațiilor de a folosi informații și funcționalități între ele, impune necesitatea realizării unui mod de comunicare transparent care să permită interacțiunea independent de specificul tehnologiei folosite în implementarea acestora.
De asemenea, aplicațiile software distribuite care comunica și iteractioneaza între diferite calculatoare pentru pe a oferi servicii sunt larg răspândite. Astfel că tendințele actuale în ceea ce privește organizarea resurselor computaționale sunt acelea de a folosi servicii pentru a pune la dispoziție sau pentru a procesa date.
Concepul de servicii web (web services) a căpătat o mare importantă în ultimii ani. Serviciile web pot fi în special foarte utile pentru crearea de aplicații ENTERPRISE și pentru a permite diverselor tehnologii software că Java EE și .NET să interopereze între ele.
Lucrarea de față își propune implementarea unor servicii web bazate pe mesaje SOAP și pe protocolul XML de comunicare. Orice software care va folosi aceste servicii web bazate pe SOAP va putea transmite date la server și va putea folosi serviciile expuse de acesta în vederea prelucrării corespunzătoare a datelor trimise.
Capitolul I. ARHITECTURA ENTERPRISE
Creșterea complexității sistemelor software atrage după sine utilizarea paradigmei de arhitectură software a sistemului. Datorită definițiilor pentru termenul de arhitectură software, s-a impus standardizarea terminologiei, ceea ce a condus la apariția standardului IEEE 1471. Conform acestui standard, conceptul de arhitectură software este „organizarea fundamentală a unui sistem reprezentatat prin componentele acestuia, relațiile dintre ele și principiile care stau la baza conceperii și evoluției sistemului” [3]. Ca atare, arhitectura software oferă o viziune de nivel înalt asupra sistemului, punând în evidență structura acestuia, dar ascunzând detaliile de implementare.
Arhitectura aplicațiilor este un instrument esențial pentru cei care se ocupă de dezvoltarea aplicației. Gradul de abstractizare utilizat în documentarea arhitecturii aplicației variază de la o organizație la alta. În timp ce unele furnizeză doar foarte abstract reprezentari fizice și logice ale modelelor tehnice utilizate, altele includ mai mult detaliu, cum ar fi modele de date comune, diagrame de comunicare între componentele aplicației, cerințele de securitate precum și aspecte legate de infrastructură.
Dintre abordările soft arhitecturale existente, pentru dezvoltarea unei arhitecturi integrate, se utilizează o arhitectură client/server pe nivele ntier,cel mai frecvent 3-tier.
I.1. Arhitectura Client – Server
La modul general, termenul de client-server desemnează un mediu în care aplicații software cer sau primesc informații una de la alta. Această condiție este îndeplinită de orice arhitectură de aplicație existentă.
Totuși, termenul de arhitectură client – server utilizat în industria software este unul mai specific : se referă la o structură particulară a unei aplicații în care clientul și server-ul au definite funcționalități specifice, dar și caracteristici diferite de implementare.
Arhitectura client server pe 2 nivele(2tier)[3]
La modul general, această arhitectură a fost compusă din clienți multipli (fat clients) și în care fiecare dintre ei trebuia să se conecteze la un sistem de stocare persistentă a datelor aflat pe un server central (Figura 1).
Aplicația client era responsabilă de partea de procesare incluzând și partea de prezentare, dar și de partea responsabilă de accesarea datelor de la baza de date.
I.2. Arhitectura Multi-Nivel Distribuita
Aplicațiile structurate pe componente distincte cu responsabilități specifice și bine delimitate au devenit o alternativă mai bună la arhitectura inflexibilă a sistemelor pe 2 nivele. Astfel, arhitectura client-server pe mai multe nivele (multi – tier), așa cum este arătat în Figura 2, împarte clientul monolitic (cu responsabilități atât pentru nivelul de prezentare, dar și pentru cel de prelucrare logică a datelor) în componente separate conceptual (3tier : nivelul client – nivelul de prezentare, nivelul de mijloc – nivelul logic, nivelul de stocare a datelor).
Arhitectura client server pe n nivele(n-tier)[3]
Această variantă permite o flexibilitate mai mare a aplicațiilor, deoarece clientul poate apela la serviciile mai multor servere pentru a satisface o cerere, iar serverul la rândul său poate apela serviciile altei componente server. De asemenea, partajarea și gestionarea pool – ului de conexiuni a bazei de date de către componente specifice server-ului localizate pe servere de aplicații specializate a redus accesul concurent la server-ul de baze de date.
Cu toate acestea, avantajele au atras după ele și o serie de dezavantaje cum ar fi, de exemplu:
creșterea complexității prin necesitatea de a crea aplicații care să se ocupe de tratarea concurentă a cererilor multiple;
creșterea eforturilor de mentenanță datorită introducerii nivelului de mijloc;
utilizarea apelurilor de procedură la distanță pentru comunicarea componentelor distribuite între client și server a introdus probeme similare cu modelul client-server (2tier) în ceea ce privește utilizarea resurselor și gestionarea conexiunilor.
I.3. Arhitectura bazată pe Servicii Web
“Serviciile Web, la nivel elementar, pot fi considerate o arhitectură universală client-server care permite sistemelor diferite să comunice între ele fără să folosească librării client proprietare” [4].
Arhitectura bazată pe Serviciile Web este o nouă abordare a aplicațiilor de e-business. Poate fi observată o transformare progresivă de la sisteme orientate pe obiecte către sisteme de servicii. Sistemele bazate pe servicii Web permit un nivel înalt de decuplare. Astfel de sisteme sunt compuse din servicii ce conțin mesaje și servicii. Serviciile sunt detectate de applicatii folosind descoperirea de servicii.
I.4. Arhitectura orientată pe servicii (SOA)
I.4.1. Ce este SOA?
Arhitectura Orientată pe Servicii (SOA) este un nou stil de arhitectură pentru dezvoltarea de aplicații distribuite cu un nivel înal de decuplare și de interoperabilitate.
SOA utilizează serviciul ca și componentă reutilizabilă spre deosebire de arhitecturile
orientate pe obiecte unde se reutilizau clase și obiecte sau a celor orientate pe componente
unde ceea ce se reutiliza erau entitățile.
Arhitectura orientată pe servicii (SOA) [16]
SOA prezintă o nouă metodă pentru crearea aplicațiilor distribuite unde serviciile pot fi publicate, descoperite și combinate cu scopul de a crea servicii și mai complexe. Aplicațiile interacționează cu serviciile prin intermediul unui punct de acces terminal (endpoint) și nu la nivel de implementare. Astfel, aplicațiile devin mai flexibile datorită abilității de a interacționa cu oricare altă aplicație ce implementează contractul stabilit între serviciu și aplicație.
De fapt, arhitectura orientată pe servicii (SOA) este o colecție de mai multe servicii expuse în rețea.
Obiectivele unei arhitecturi orientate pe servicii sunt :
Cuplarea slabă prin descompunerea în servicii independente care ajută astfel la scăderea dependenței de un singur proces;
Neutralitatea de platformă prin transmiterea de mesaje bazate; de exemplu, pe XML este crescută capacitatea de a atinge neutralitatea de platformă. Astfel că se asigură interoperabilitatea între aplicațiile implementate utilizând tehnologii diferite (de exemplu: un serviciu Java poate fi utilizat de o aplicație dezvoltată folosind C++ sau oricare limbaj de programare).
Interoperabilitate SOA independentă de platformă
Standardizare prin faptul că serviciile trebuie să depindă numai de descriere, iar transmiterea mesajelor este bazată pe standarde acceptate.
Reutilizarea prin faptul că logica este divizată în unități logice mici care pot fi ușor reutilizate : de exemplu, prin compunerea de servicii se poate obține un nou serviciu agregat mai complex, prin utilizarea aceluiași serviciu de către mai multe procese business.
Reutilizarea serviciilor
Scalabilitate deoarece procesele fiind descompuse în unități mici fac posibilă adăugarea facilă de logici noi fie ca o extindere a unui serviciu deja existent, fie ca fiind construită ca un serviciu nou.
În concluzie, SOA reprezintă o îmbunătățire a dezvoltărilor de tip orientat pe obiect (OO) sau dezvoltare bazată pe componente (CBD) prin faptul că reține elemente importante de la fie4.1. Ce este SOA?
Arhitectura Orientată pe Servicii (SOA) este un nou stil de arhitectură pentru dezvoltarea de aplicații distribuite cu un nivel înal de decuplare și de interoperabilitate.
SOA utilizează serviciul ca și componentă reutilizabilă spre deosebire de arhitecturile
orientate pe obiecte unde se reutilizau clase și obiecte sau a celor orientate pe componente
unde ceea ce se reutiliza erau entitățile.
Arhitectura orientată pe servicii (SOA) [16]
SOA prezintă o nouă metodă pentru crearea aplicațiilor distribuite unde serviciile pot fi publicate, descoperite și combinate cu scopul de a crea servicii și mai complexe. Aplicațiile interacționează cu serviciile prin intermediul unui punct de acces terminal (endpoint) și nu la nivel de implementare. Astfel, aplicațiile devin mai flexibile datorită abilității de a interacționa cu oricare altă aplicație ce implementează contractul stabilit între serviciu și aplicație.
De fapt, arhitectura orientată pe servicii (SOA) este o colecție de mai multe servicii expuse în rețea.
Obiectivele unei arhitecturi orientate pe servicii sunt :
Cuplarea slabă prin descompunerea în servicii independente care ajută astfel la scăderea dependenței de un singur proces;
Neutralitatea de platformă prin transmiterea de mesaje bazate; de exemplu, pe XML este crescută capacitatea de a atinge neutralitatea de platformă. Astfel că se asigură interoperabilitatea între aplicațiile implementate utilizând tehnologii diferite (de exemplu: un serviciu Java poate fi utilizat de o aplicație dezvoltată folosind C++ sau oricare limbaj de programare).
Interoperabilitate SOA independentă de platformă
Standardizare prin faptul că serviciile trebuie să depindă numai de descriere, iar transmiterea mesajelor este bazată pe standarde acceptate.
Reutilizarea prin faptul că logica este divizată în unități logice mici care pot fi ușor reutilizate : de exemplu, prin compunerea de servicii se poate obține un nou serviciu agregat mai complex, prin utilizarea aceluiași serviciu de către mai multe procese business.
Reutilizarea serviciilor
Scalabilitate deoarece procesele fiind descompuse în unități mici fac posibilă adăugarea facilă de logici noi fie ca o extindere a unui serviciu deja existent, fie ca fiind construită ca un serviciu nou.
În concluzie, SOA reprezintă o îmbunătățire a dezvoltărilor de tip orientat pe obiect (OO) sau dezvoltare bazată pe componente (CBD) prin faptul că reține elemente importante de la fiecare : procesele sunt constituite din bucăți mici de software ce pot fi interpretate ca fiind analog “componentelor” din CBD și logica din interiorul componentelor este bazată pe principiile programării orientate pe obiect ca și în OO.
I.4.2. Cum este structurată o arhitectură SOA?
Într-o arhitectură orientată pe servicii se disting trei componente de bază:
Furnizorul de Servicii (Serviciu) : nod în Internet care printr-o interfață asigură accesul la un serviciu software care execută un anumit set de operații;
Consumatorul de Servicii (Consumator) : nod în rețea care se leagă la Furnizorul de Servicii și folosește funcționalitatea oferită de acesta, construind soluția de afacere ("businesssolution");
Servicii Director (Broker) : nod în Internet unde sunt stocate informații despre furnizorii de servicii.
Serviciul care este disponibil consumatorului este publicat în serviciile director la broker. Consumatorul se conectează și descoperă servicille de la Broker pentru a obține informațiile despre interfețele pe care le expun Furnizorii de Servicii. Dacă serviciul este găsit, se oferă legătură la serviciu și se execută logica de procesare.
Capitolul II. SERVICII WEB
II.1. Ce este un serviciu web?
Serviciul web este o realizare de SOA. Este important de reținut că SOA reprezintă un model arhitectural, care este independent de orice platformă de tehnologie și servicile Web reprezintă cea mai populară implementare a SOA.
După cum sugerează și numele, serviciile web oferă servicii de pe rețeaua de web. Acest lucru nu este surprinzător, deoarece alegerea rețelei de Internet conectează deja mai multe sisteme diferite din întreaga lume.
Există mai multe definiții pentru serviciile Web și am considerat important să menționez două dintre ele în mod special crezând că reușesc să capteze într-adevăr esența a ceea ce înseamnă serviciile Web :
În primul rând, "Un serviciu web este orice modul de softwarecare se expune pe internet și care folosește un sistem standardizat de mesagerie XML. XML este utilizat pentru a codifica toate comunicațiile de la și la un serviciu web. De exemplu, un client invocă un serviciu web prin faptul că trimite un mesajXML, apoi așteaptă un răspuns de XML corespunzator. Deoarece toată comunicarea este în XML, serviciile Web nu sunt legate de niciun sistem de operare sau de vreun limbaj de programare : Java poate vorbi cu Perl; aplicațiile Windows pot vorbi cu aplicații Unix"[5].
În al doilea rând, "Un serviciu web este o colecție de protocoale deschise și standarde utilizate pentru schimbul de date între aplicații sau sisteme. Aplicații software scrise în diferite limbaje de programare și care rulează pe diverse platforme pot utiliza servicii web pentru un schimb de date prin rețele de calculatoare, cum ar fi internetul într-un mod similar cu inter-comunicarea pe un singur calculator. Aceste interoperabilitati (de exemplu, între aplicații Java și Python, sau Windows și Linux), se datorează utilizării de standarde deschise "[6].
Astfel, serviciile web sunt independente de platformă, bazate pe mesaje XML. Ideea este de a distribui serviciile pe Internet și de ale face disponibile pentru clienți. Aceste servicii pot fi astfel puse în aplicare cu orice limbaj și poate fi invocate, precum și compuse. Cel mai important factor al succesului și al popularității serviciilor Web este faptul că utilizează ca bază XML – ul.
În această secțiune voi realiza o scurtă descriere a serviciilor web și voi introduce diverse tehnologii de servicii web.
II.2. Arhitectura serviciilor Web
Arhitectură serviciilor Web utilizează tehnologii diferite ce permit unui client să obțină date sau să execute anumite operații de la un server, utilizând protocolul SOAP.
Un serviciu Web oferă o interfață de programare a aplicațiilor (API) ce facilitează comunicarea aplicațiilor folosind mesaje XML prin web sau printr-o conexiune de rețea. Acest sistem a fost creat ca și agent intermediar pentru cazurile de integrare inter-aplicații.
SOAP servește drept entitate care utilizează XML pentru a colecta mesaje specifice, serviciul, interfața sau tipul de port și legătura serviciului (legătura conține informații despre serviciu cum ar fi redirecționarea gazdei și punctual de acces).
În cadrul unei arhitecturi Web service se disting cele trei roluri mari, roluri specifice unei arhitecturi SOA:
furnizorul de servicii;
consumatorul de servicii;
serviciul de înregistrare (broker-ul).
În Figura 6 se redă arhitectura serviciilor Web la nivel logic ilustrând legătura dintre rolurile și operațiile serviciilor web.
Arhitectura servicii Web [18]
II.3. Cum funcționează serviciile Web?
Comunicația între cele trei componente se realizează cu ajutorul lui HTTP, între ei transferandu-se mesaje SOAP (care sunt de fapt mesaje XML formatate conform standardului SOAP).
Broker-ul folosește protocolul UDDI (Universal Description, Discovery and Integration) pentru căutarea și actualizarea informațiilor din baza sa de date cu privire la localizarea serviciilor Web înregistrate.
După localizarea serviciului Web, acesta este interogat pentru a obține informații despre metodele sale, respectiv interfața pe care o expune, informații organizate sub forma unui document WSDL (Web Services Description Language). Broker-ul returnează apoi clientului un fișier WSDL pe care aplicația îl va trata ca pe un mesaj SOAP.
Cererea împachetată ca mesaj SOAP este apoi trimisă server-ului de aplicație ce găzduiește serviciul web destinat executării. Folosind instrucțiunile SOAP, serviciul Web poate executa corect operațiile cerute în concondanță cu acei parametri primiți și poate oferi răspunsul/rezultatul entității care a emis cererea tot sub forma unui mesaj SOAP.
II.4. Structura protocolului unui Web service
Structura protocolului specific unui serviciu Web variază de la o organizație la alta, numărul și complexitateta nivelelor stivei protocolului depinzând de nevoile organizației.
Structura de bază a stivei protocolului utilizat de un Web service este prezentată în Figura 7.
Stiva protocolului de Web Service [19]
Transportul : nivelul transport este responsabil de transmiterea mesajelor între aplicații. Acest nivel implementează, de obicei, protocolul HTTP, SMTP (Simple Mail Transfer Protocol), file transfer protocol (FTP) și protocoale mai noi ca și BEEP (Blocks Extensible Exchange Protocol) [17]
Codarea XML a mesajelor : nivel responsabil de codarea mesajelor într-un format comun – format XML – astfel încât mesajele să poată fi înțelese de ambele aplicații ce comunică între ele (clientul ce solicită serviciul și furnizorul de servicii). În prezent acest nivel include XML-RPC și SOAP.
Formatul mesajelor (SOAP) : comunicarea între client și serviciu (server) trebuie să folosească o metodă comună de codare și formatare pentru mesajele schimbate între ele. SOAP este un protocol de mesaje XML simplu responsabil de transferul datelor între diferite servicii Web. Este bazat pe XML și folosește în mod obișnuit un protocol de transport pe Internet ca și HTTP pentru a trimite mesajele.
Descrierea serviciilor (WSDL) : scopul acestui nivel este de a defini interfața publică a unui serviciu Web specific. În mod curent, descrierea serviciului Web este realizată prin WSDL (Web Service Description Language) care este bazat pe XML.[17]
Clientul folosește informația furnizată de documentul în care este descris serviciul solicitat odată ce endpoint-ul (locația serviciului web) a fost descoperit. Astfel, descrierea serviciului furnizată de documentul WSDL cuprinde metadate structurate despre interfața care va fi implementată (consumată) de aplicația client.
Descoperirea serviciului : un nivel responsabil de înregistrarea serviciilor într-o bază de date comună (registru) și de expunerea unui mecanism ușor pentru descoperirea serviciilor înregistrate. Acest nivel este impelmentat adesea utilizând UDDI (Universal Description, Discovery and Integration) [17].
II.5. Caracteristici ale serviciilor Web
Se pot enumera următoarele caracteristici ale serviciilor Web :
Bazate pe XML : serviciile Web se bazează pe utilizarea XML-ului pentru transmiterea și reprezentarea datelor. Utilizarea XML-ului facilitează evitarea oricărei dependențe de specificul rețelei de transport, de sistemul de operare sau de platforma de dezvoltare.
Decuplare : nu există dependență directă între serviciul Web și utilizatorul său. Modificări ale intefeței nu afectează capacitatea clientului de a interacționa cu serviciul, în timp ce în sisteme cu un grad de cuplare pronunțat logica clientului și a serverului sunt strâns dependente de fiecare. Astfel, implementarea de arhitecturi cu nivel de cuplare redus (loosly coupled) facilitează gestionarea aplicațiilor software și ușurează integrarea cu alte sisteme.
Abilitatea Web service-urilor de a fi sincrone și asincrone :
În cadrul serviciilor web se pot utiliza trei moduri principale de comunicație:
comunicație sincronă(RPC) : clientul trimite o cerere SOAP furnizorului de servicii și așteaptă un răspuns SOAP fără a mai executa alte operații în timpul acestei perioade.
comunicație unidirecțională (orientată pe mesaje): clientul trimite o cerere SOAP și nu așteaptă nici un răspuns SOAP din partea furnizorului de servicii și poate executa deci imediat alte operații (fire and forget model);
apel asincron cu apelarea înapoi a inițiatorului (asynchronous callback ) : client-ul apelează un serviciu prin una din cele două metode de mai sus. Ulterior, cele două entități își schimbă rolul, în vederea apelării înapoi a inițiatorului. Acest model de comunicație poate fi construit pe oricare din cele două metode de comunicație menționate.
Oferă suport pentru apelul procedurilor la distanță (RPCs – Remote Procedure Calls). Serviciile Web permit clienților să apeleze metode și operații pe obiecte aflate la distanță (remote objects) folosind un protocol bazat pe XML, în speță protocolul SOAP.
Oferă suport pentru pentru schimbul de mesaje document : un aspect important este faptul că prin utilizarea XML-ului se pot reprezenta date, documente simple și chiar complexe într-un mod generic.
II.6. Beneficii ale utilizării servicilor web
Următoarele beneficii se pot evidenția în urma utilizării de servicii Web [17][6] :
Reutilizare : un serviciu Web este o componentă care poate fi accesată la distanță folosind protocolul HTTP. Serviciile Web reprezintă o modalitate de a face disponibil un cod deja existent prin rețeaua Internet. Ca și rezultat, funcționalitățile programului pot fi apelate și de alte aplicații.
Interoperabilitate : Servicile Web fac posibil schimbul de date și comunicarea între diferite aplicații diferite independent de platformă și de tehnologiile utilizate.
Protocol standardizat: serviciile Web utilizează protocoale standard pentru comunicare. Toate cele 4 nivele (Transport, Codare și Formatare XML a mesajelor, Descrierea Serviciului și Descoperirea Serviciului) utilizează protocoale bine definite. De asemenea, este standardizată și structura (stiva) protocolului serviciilor Web.
Descoperire automată: primul pas pentru a accesa un serviciu Web este prin procesul de descoperire a serviciilor. Clientul face cerere la serviciul de înregistrare pentru un serviciu Web de care are nevoie. După ce procesul de descoperire este încheiat, clientul poate accesa serviciu Web.
Capitolul III. TEHNOLOGII PENTRU SERVICII WEB
Acest capitol va descrie în mare concepte referitoare la SOAP, WSDL și la descoperirea serviciului web.
III.1. Protocolul SOAP (Simple Object Access Protocol)
Este protocolul utilizat pentru transmiterea datelor de către serviciile Web. Astfel, SOAP reprezintă protocolul folosit în vederea transmiterii informației în sisteme distribuite facilitând în acest mod interoperabilitatea dintre acestea. Acest scop a putut fi atins urmând aceleași principii pe care le-au urmat alte protocoale web de succes: simplitate, flexibilitate, acces ușor prin firewall, independența față de platformă și mesaje bazate pe XML.
Un mesaj SOAP s-a dorit la început a fi doar un document XML formatat și deci, altfel spus, un document text pur. Totuși, SOAP a evoluat de-a lungul timpului dintr-un simplu protocol la un adevărat framework pentru realizarea schimbului mesajelor între clienți și serviciile Web.
SOAP asigură schimbul liber de date prin utilizarea protocoalelor deja existente (HTTP, SMTP etc.) pentru a permite mesajelor SOAP să fie trimise ca parte a mesajelor acestor protocoale.
Pentru securizarea accesului la rețele se utilizează firewall – uri, proxiuri și alte elemente de securizare care, de regulă, blochează orice comunicație neautorizată în afară de datele primite pe HTTP. De aceea, acesta este și unul din motivele pentru care s-a ales ca mesajele SOAP să fie trimise ca parte a mesajelor HTTP într-un proces numit transmiterea SOAP peste HTTP.
Însă, mesajele SOAP nu sunt restrânse la a fi transmise doar utilizând protocolul HTTP pentru transport. Responsabilitatea protocolului SOAP este să definească modul în care este format un mesaj și nu cel în care este trimis un mesaj. Astfel, și alte protocoale că SMTP sau FTP pot fi utilizate [9].
III.1.1. Structura mesajelor SOAP
Structura mesajelor SOAP este relativ simplă. Un mesaj SOAP este compus din 2 secțiuni obligatorii: plicul <Envelope> și corpul <Body> , dar și o secțiune opțională antet <Header>.
Orice element este prefixat cu spațiul de nume “soap” definit în spațiul de nume în elementul și se aplică tuturor elementelor conținute în spațiul de nume SOAP.
Structura mesajului SOAP
Un exemplu general de structură a unui mesaj SOAP este :
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
…
</soap:Header>
<soap:Body>
…
<soap:Fault>
…
</soap:Fault>
</soap:Body>
</soap:Envelope
– Elementul plic <Envelope> reprezintă elementul-rădăcina al mesajului XML SOAP. Este obligatoriu și conține elementele <Header> și <Body>.
În plic <Envelope> se declară și spațiile de nume standard utilizate de protocolul SOAP precum și pentru atribute suplimentare dacă acestea sunt prezente.
Se pot specifica două scheme:
o xsd ce definește spațiul de nume pentru definiția schemei XML . În exemplul prezentat se va folosi codificare din schema 2001.
o xsi definește spațiul de nume utilizat pentru atributele elementului din shcema XML.
– Elementul antet <Header> este un element facultativ fiind utilizat cu scopul de a oferi posibilitatea de a extinde conținutul/informația mesajului fără să schimbe în mod fundamental structura mesajului SOAP. Datorită acestei separații se pot adăuga funcționalități noi – de exemplu: securitate, managementul tranzacțiilor – fără să se modifice specificațiile.
– Elementul corp <Body> este un element obligatoriu ce va conține mesajul de SOAP în format XML. Toate elementele conținute de elementul corp (<Body>) se numesc înregistrări corp și trebuie să urmeze imediat după acesta.
Ca și mesaj-răspuns, acest element va conține fie răspunsul propriu-zis, fie un mesaj de eroare. În interiorul elementului corp (<Body>) informația poate conține fie date în format XML, fie informații despre un apel de metodă cu argumentele asociate, răspunsul la un apel de metodă sau/și un mesaj de eroare.
Ca mesaj de cerere, datele cererii reprezintă date specifice aplicației care sunt transmise unui Web service. Aceste date pot fi date XML sau parametri ai unui apel de metodă.
– Elementul eroare (<Fault>) este un element opțional ce conține informații despre erorile care au apărut în timpul procesării a mesajului.
Dacă este prezent, atunci acesta reprezintă o înregistrare-corp și poate apărea doar o singură dată în elementul părinte <Body>.
Elementul eroare <Fault> poate conține 4 sub-elemente :
– faultcode : utilizat de consumatorul serviciului Web pentru a identifica eroarea la primirea răspunsului. Coduri de erori SOAP standard sunt definite de protocolul SOAP ce acoperă principalele erori SOAP.
– faultstring : utilizat pentru a furniza o descriere mai amănuntită despre eroare.
– faultfactor : utilizat pentru a oferi informații despre cauza erorii și pentru a identifica sursa unei erori apărute folosind un URI. Aplicațiile ce nu sunt destinația finală (consumatorul) a unui mesaj SOAP trebuie să includă acest element în elementul părinte <Fault>.
– detail : folosit pentru a stoca mai multe informații specifice erorii. Absența acestuia dintr-un element indică faptul că nu este vorba de o eroare legată de procesarea elementului <Body>.
III.1.2. Stiluri in comunicarea SOAP
Modelul de comunicare a serviciilor Web descrie modul în care să se apeleze serviciile Web și se bazează pe SOAP. Modelul de comunicare SOAP este definit prin stilul de comunicare și prin cel de codare. Astfel, SOAP oferă suport pentru două stiluri de comunicare : comunicare RPC și comunicare și document (mesaj).
Servicile Web bazate pe RPC (Remote Procedure Call): în această modalitate de comunicare serviciile web sunt văzute ca și obiecte la distanță (remote objects) de către aplicațiile clienți. Clienții trimit ca cerere apelul metodei.[9]
Această informație este formatată ca și un set de elemente XML conținute într-un mesaj SOAP ce este ilustrat în exemplul ce urmează:
<Envelope xmlns="http://www.w3.org/2001/12/soap-envelope"
<Header>
…
</Header>
<Body>
<GetMediaMetadata>
<mediaId>4562</mediaId>
</GetMediaMetadata>
</Body>
</Envelope>
Serviciile Web în stilul Document (orientat pe mesaj)
SOAP oferă suport pentru transmiterea oricăror date XML utilizând schimbul de documente ca și metodă de comunicare.
Spre deosebire de stilul RPC, stilul Document este diferit prin faptul că parametrii serviciului sunt trimiși de la client către server într-un document XML obișnuit în loc să utilizeze un set de valori și metode ca și parametri.
La primirea documentului XML furnizorul de servicii prelucrează documentul, execută operația și va trimite răspunsul înapoi spre client sub forma unui document XML obișnuit. În acest fel nu există nicio corespondență între obiectele de pe server (apel de metode, parametri) și valorile din documentele XML.
Mesajul SOAP în stilul Document XML poate transporta unul sau mai multe documente în corpul său. Astfel, neexistand nicio constrângere legată de alcătuirea conținutului unui asemenea mesaj, structurarea documentului are loc la nivelul aplicației. Și ceea ce este și mai important este faptul că serviciile Web în stilul Document urmează paradigma de procesare asincronă.
<soap:Envelope xmlns:SOAP=http://www.w3.org/2001/12/soap-envelope>
<soap:Body>
<pourchaseOrderorderDate=”2009-05-20” xmlnso=http://www.amzon.com/POs>
<po:accountName>Ricard</po:accountName>
<po:accountNumber>1234</po:accountNumber>
<po:book>
<po:title>J2EE web services</po:title>
<po:quantity>300</po:quantity>
<po:price>24.5</po:price>
</p:book>
</pourchaseOrder>
</soap:Body>
</soap:Envelope>
III.1.3. Avantaje si dezavantaje ale protocolului SOAP
Printre avantajele care merită precizate cu privire la utilizarea SOAP se pot menționa:
Simplitate: SOAP este simplu și folosește XML care este bine structurat și ușor de parse – uit.
Portabilitate : SOAP este independent de platformă și deci este portabil.
Acces facil prin firewall : SOAP este capabil de a trece de firewall care blochează total comunicarea prin alte protocoale. Acest lucru este posibil prin utilizarea protocolului HTTP.
Standard deschis : SOAP este bazat pe Standardul XML pentru a formata datele. Drept urmare, SOAP devine ușor de extins și de adoptat.
Impact scăzut la schimbări : modificări viitoare ale infrastructurii SOAP nu se vor reflecta major la nivelul aplicațiilor care deja îl utilizează.
Ca si dezavantaje se pot menționa:
SOAP poate fi destul de lent ca și transmisie de date datorită lungimii formatului XML, dar și datorită utilizării comunicării pe HTTP în comparație cu alte tehnologii middleware (CORBA).
Anumite implementări SOAP limitează cantitatea de date transmise.
SOAP este un protocol fără stare (stateless) aceasta însemnând că, în cazul în care sunt necesare mai multe conectări, aplicația ce inițiază cererea trebuie să se autentifice la fiecare conexiune ca și cum s-ar conecta pentru prima dată.
Deoarece SOAP a fost la început în principal bazată pe HTTP, acest lucru a impus o arhitectură cerere-răspuns care nu este potrivită pentru toate situațiile.
III.2. Descrierea serviciilor Web
Conform [20] o definiție a limbajului WSDL (Web Services Description Language) utilizat pentru descrierea serviciilor este :
“WSDL este un format XML pentru descrierea serviciilor de rețea ca un set de endpoints care operează pe mesaje conținând informație orientată document sau orientată procedură. Operațiile și mesajele sunt descrise abstract și apoi asociate cu un protocol de rețea concret și cu un format de mesaj pentru a defini un endpoint. Endpoint – uri concrete înrudite sunt combinate în endpoint-uri abstracte (servicii). WSDL este extensibil pentru a permite descrierea endpointurilor și a mesajelor indiferent de formatul mesajelor sau de protocolul de rețea utilizat pentru comunicare”
Limbajul de descriere a serviciilor web facilitează separarea descrierii la nivel abstract a funcționalității oferite de un servicu de detaliile concrete de utilizare.Astfel, utilizând WSDL se pot descrie serviciile începând cu mesajele interschimbate între entitatea care furnizează și cea care apelează un serviciu specific.
Serviciile sunt definite prin WSDL ca o colecție de porturi sau ca puncte terminale (endpoints) într-o rețea.
Definirea porturilor și a mesajelor este abstractă și separată de modul de întrebuințare concretă, acest fapt facilitând reutilizarea acestor definiri. Portul este definit ca asocierea dintre o adresa de rețea cu o legătură reutilizabilă și o colecție de porturi, ceea ce definește de fapt un serviciu.
Mesajele sunt descrieri ale datelor la modul abstract, acestea urmând a fi interschimbate, iar tipurile de porturi sunt colecții abstracte ale operațiilor suportate.
Mesajele sunt specificate la modul abstract și apoi sunt asociate unui protocol de rețea și se specifică, de asemenea, și un format al mesajelor (o sintaxă). Un mesaj conține o colecție de date de anumite tipuri și procesul de schimb al mesajelor este definit ca și operație. Tipurile de date utilizate în mesaje se definesc prin intermediual unei scheme XML, iar la nivel conceptual se folosește un model de date definit printr-un set de componente mesaj, port, manieră de atasare, serviciu).
O legătură reutilizabilă este reprezentată de protocolul concret și de formatul de date specificat pentru un anumit tip de porturi.
Pe această cale, WSDL descrie interfața publică pentru serviciile Web.
Utilizat în combinație cu SOAP și XML Schema, limbajul WSDL poate oferi servicii prin intermediul internetului. Programul client care se conectează la un serviciu web poate citi documentul WSDL pentru a determina ce funcții sunt expuse de acest server. Clientul poate utiliza SOAP pentru a apela una din funcțiile conținute de WSDL.
În concluzie, Web Services Description Language (WSDL) este deci o gramatică XML folosită pentru a descrie un serviciu Web în termeni de mesaje pe care le acceptă și mesaje pe care le generează. Cu alte cuvinte, un fișier WSDL reprezintă un contract între un consumator de servicii Web (client) și un serviciu Web.
III.2.1. Structura unui document WSDL
Conform [7], documentul WSDL ce descrie un serviciu poate fi separat în 2 părți:
Descrierea abstractă: secțiune care furnizeză informații despre caracteristicile interfeței serviciului Web fără nicio descriere sau detaliu în ceea ce privește tehnologia folosită la implementarea serviciului web sau despre cea utilizată la trimiterea mesajelor. Astfel se asigură integritatea serviciului web în eventualitatea unei schimbări a tehnologiei utilizate [7].
Descrierea concretă: secțiune a documentului WSDL ce definește conexiunea la implementarea reală a serviciului Web unde este logica sa de implementare. Această descriere conține trei părți : binding, port și serviciu [7].
Documentul WSDL reprezintă o listă de definiții. Într-un astfel de document WSDL elementul-rădăcină este numit definitions. Acesta conține 5 fii imediați folosiți pentru a defini un serviciu web. Cele 5 elemente care urmează apar în cadrul elementului definitions, într-un fișier WSDL în ordinea specificată:
– elementul <types> care definește tipurile de date folosite pentru schimbul de mesaje;
– elementul <message> care descrie mesajele utilizate în comunicare;
– elementul <portType> care identifica un set de operații și mesajele atașate fiecăreia dintre ele; este vorba, de fapt, despre o interfață a serviciului.
Structura WSDL pentru descrierea unui serviciu
– elementul <binding> care specifică detaliile de protocol utilizate de operațiile serviciului și care descrie modul în care se traduce conținutul abstract al acestor mesaje într-un format concret;
– elementul <service> care grupează un set de port-uri corelate între ele.
Elementul <types>
Întâi de toate sunt definite tipurile de mesaje folosite în schimbul de mesaje. Acest lucru reprezintă, în principal, definirea tipurilor utilizând XML Schema Definition Language.
Elementul <message>
Pe lângă definirea tipurilor de date care sunt transmise înainte și înapoi în timpul invocării unei metode web, este important de asemenea să fie definite mesajele de cerere și de răspuns. Și aceasta deoarece mesajele sunt independente de protocol, astfel că se poate folosi un mesaj cu HTTP-GET, HTTP-POST, SOAP sau orice alt protocol pe care un ofertant de servicii web îl suportă.
În cazul în care se uzează de SOAP, elementul <message> corespunde încărcăturii utile a unui mesaj SOAP de cerere sau de răspuns. În acesta nu sunt incluse elementele SOAP <Envelope> și <Fault>. Și aceasta datorită faptului că mesajele pot avea orice nume având în vedere că WSDL nu definește o convenție de denumire pentru mesaje.
Un element <message> conține 0 sau mai mulți fii <part>.
Un mesaj de cerere include toți parametrii in și inout. De asemenea, un mesaj de răspuns conține toți parametrii out și inout. Este necesar ca fiecare element <part> să aibă un nume și un tip de dată care se poate potrivi cu tipurile de date utilizate în implementarea serviciului.
Elementul <portType>
Cel pe care îl vom numi un ofertant de servicii web (respectiv, un nod din rețea care este server web) are posibilitatea de a expune mai multe servicii web. Un singur serviciu web poate suporta invocarea metodelor sale folosind o multitudine de protocoale. Este posibil ca formatul datelor schimbate între client și serviciul web să depindă de protocolul folosit cu scopul de a invoca o metodă.
Tocmai de aceea este imperios necesar să existe o modalitate de a asocia operațiile cu endpointurile de unde acestea pot fi accesate. Un astfel de tip de asociere se poate realiza utilizând elementul <portType>.
Elementul <binding>
În continuare, după definirea portului logic (portType), se evidențiază cum poate un consumator al serviciului Web să se lege la portul pe care este disponibilă operația. Aceasta implică asocierea unei operații cu un protocol și asigurarea oricărei informații de legătură specifice protocolului. Pentru a realiza asta se utilizează elementul <binding>.
Elementul <service>
Spre finalul fișierului WSDL sunt definite endpointurile pentru fiecare dintre protocoalele care se pot folosi în vederea accesării unui serviciu web. Pentru a nominaliza endpointurile se folosește elementul <service>.
III.3. UDDI (Universal Description, Discovery and Integration)
Reprezintă o colecție de specificații pentru registre distribuite de informații legate de servicii Web. Aceste registre pot fi accesate prin web. Specificațiile sunt divizate în mai multe categorii. Dintre acestea, două sunt esențiale pentru un dezvoltator de servicii Web: "UDDI programmers API" (API pentru programatorii UDDI) și "UDDI Data Structure Specification" (Specificația structurilor de date UDDI). Versiunile curente ale acestor specificații pot fi găsite la http://www.uddi.org.
Un sistem de registre bazat pe XML independent de platformă;
Facilitarea comunicării între serviciile oferite de firme:White Pages,Yellow Pages, Green Pages;
Implementează conceptul de “service broker”;
Este interogat de mesaje SOAP care au nevoie de un serviciu Web;
Oferă acces către documentul descriptiv WSDL al serviciului Web;
Acceptare redusă.
III.3.1. API pentru programatorii UDDI
Specificația în discuție definește funcțiile responsabile de un model de cerere/răspuns cu scopul de a accesa registrele UDDI. Astfel, există 2 tipuri de API definite în această specificație:
API-ul publisher pentru producătorii de servicii web care doresc să publice informații despre acestea în cadrul unui registru UDDI.
API-ul inquiry care oferă posibilitatea de citire a informației dintr-un registru.
De menționat ar fi și faptul că specificația API pentru programatorii UDDI definește circa 40 de mesaje SOAP utilizate în vederea căutării și publicării de informație referitoare la serviciile web în registrele UDDI.
III.3.2. Beneficiile utilizării UDDI
Datorită posibilității de înregistrare a serviciilor Web oferite de companii într-un registru UDDI se permite:
Listarea și descrierea regulilor de urmat prin care partenerii de afaceri pot colabora;
Mărirea vizibilității și accesibilității companiei în cadrul căutărilor unor eventuali cumpărători, dar și pe piețele din întreaga lume.
III.3.3. Informațiile oferite de UDDI
UDDI are capacitatea de a oferi răspunsuri la query-uri astfel:
ce servicii web oferă un anumit tip de afacere;
care sunt endpointurile cunoscute pentru un anumit serviciu Web;
care este informația de legătură (binding) (care sunt protocoalele suportate) pentru un anumit endpoint.
Astfel, un sistem orientat pe serviciu trebuie să dețină un registru care se ocupă de asocierea serviciului corespunzător cererii primite și care funcționează ca și sistem de regăsire a serviciului corect ce urmează a fi identificat de entitatea care trimite cererea.
Așadar, mecanismul care realizează această sarcină se numește UDDI Provider (furnizor UDDI – Universal Description Discovery and Integration). Acest UDDI provider găzduiește o înregistrare standardizată care concepe profilele serviciilor înregistrate făcând în acest fel posibilă asocierea unei anumite cereri cu serviciul corespunzător.
În plus, alte interogări potențiale, ca de exemplu: comparația între prețurile serviciilor web sau apropierea geografică nu fac parte din specificația UDDI. Astfel de query-uri suplimentare și metadatele asociate lor sunt considerate servicii adiționale (value-added) pe care producătorii de servicii web sunt liberi să le implementeze și să le pună la dispoziție.
Capitolul IV. FRAMEWORK-uri și TEHNOLOGII UTILIZATE
IV.1. Spring
Spring este un framework “open source” pentru platfoma Java care asigură un suport complet de infrastructură pentru a dezvolta aplicații Java. Spring se ocupă cu infrastructura facilitându-le dezvoltatorilor de aplicații o mai bună concentrare pe aspecte mai importante în dezvoltarea aplicației.
Spring permite să se construiască aplicații utilizând obiecte simple Java (POJO) și să se aplice servicii “enterprise” non-invaziv acestor obiecte POJO. Această capabilitate se aplică la modelul de programare specific Java SE și total sau parțial la java EE..
Central în framework-ul Spring este container-ul de Inversiune a Controlului care asigură un mod consistent de configurare și gestionare a obiectelor Java. Container-ul framework-ului Spring este fie BeanFactory, fie Application Context sau unanim denumit container-ul Core.
IV.1.1. De ce este util principiul de Inversiune a Controlului?
Principiul de Inversiune a Controlului (IoC) este tehnologia cu care framework-ul Spring se identifică cel mai mult. Cu container – ul de IoC Spring realizează gestionarea dependințelor obiectelor prin injectarea dependințelor (references pushing) în obiecte în timpul rulării în loc să lase obiectele să-și seteze singure dependințele (references pulling) din mediul aplicației. Acest mod de setare a dependințelor între obiectele unei aplicații are o se serie de avantaje:
Toate clasele aplicației sunt construite cât mai simplu posibil cu minimin de comportamente și numai cu proprietățile necesare.
Toate clasele aplicației sunt documentate prin ele însele ceea ce permite realizarea unui cod mult mai ușor gestionabil.
Aplicația lasă responsabilitatea gestionării configurării framework-ului.
IoC crește consistența în gestionarea configurării codului deoarece framewok-ul se ocupă de acest aspect comun fiecărei aplicații.
IV.1.2. Ce este principiul de Invesiune a Controlului?
Principiul de inversiune a Controlului are la bază pattern-ul de Injectare a Dependintelor (Dependency Injection).
Injectarea Dependințelor este un pattern în care un container furnizează referințele de obiecte fie prin nume altor obiecte, fie prin constructori, proprietăți sau metode factory. Deci injectarea dependințelor propune separarea implementării unui obiect de contrucția obiectelor de care depind.
Container-ul de IoC este deci responsabil pentru gestionarea ciclurilor de viață ale obiectelor: crearea de obiecte, metode de inițializare și configurarea dependințelor dintre ele realizând legătură dintre ele.
IoC țintește să furnizeze un mecanism simplu pentru gestionarea obiectelor aplicației și a dependențelor sale.
Cu IoC aplicația însăși nu este responsabilă de obținerea obiectelor necesare. În schimb, Spring (sau oricare alt framework care implementează IoC) este configurat pentru a le crea pentru aplicație.
Utilizarea IoC implică două activități :
Definirea relațiilor între obiecte folosind interfețe Java sau clase abstracte.
Apelul unui obiect din afara aplicației, numit container-ul IoC pentru a instantia obiecte și pentru a le furniza acolo unde este nevoie de ele și a le gestiona ciclul de viață.
Obiectele configurate cu IoC nu sunt obligate să aibă dependințe de container-ul care le creează. Și mai mult decât atât și foarte important este că nu trebuie să știe de implementările concrete ale claselor care le relationează și nici cum să le localizeze.
Există două modalități de obținere a obiectelor:
Dependințe lookup (dependința de căutare) : un model prin care un apelant face o solicitare adresată obiectului container pentru un obiect folosind un anumit nume sau un anumit tip.
Dependința injection (de injecție) : un model prin care container-ul trimite obiecte către alte obiecte utilizând numele lor prin concepte ca și constructor, proprietăți sau metodă de creare de obiecte (factory method).
Injectarea Dependenței este o implementare particulară a principiul de Inversare a Controlului aplicat la crearea și gestionarea dependințelor în care acestea din urmă sunt injectate de container în obiectul dependent.
În mod tipic, container-ul este configurat prin încărcarea fișierelor XML de configurare ce conțin definiții ale obiectelor denumite de container Bean. Aceste fișiere de configurare furnizeză tot ceea ce este nevoie pentru ca obiectele să fie create.
În practică se utilizează trei tipuri diferite de IoC:
Injecție prin Setter: container-ul IoC folosește metode de setare de proprietăți conforme cu specificația pentru obiectele JavaBean pentru a seta dependințele.
Injecție prin constructor (Constructor injection): container-ul IoC folosește parametrii constructorului pentru a seta dependințele.
Injecție prin Metoda (Method Injection): container-ul implementează o metodă abstractă în dependenți la runtime pentru a seta dependințele pentru ele (de exemplu metoda factory).
IV.2. Implementări ale IoC Spring container
În Spring, gestionarea asocierilor dintre componente se realizează cu ajutorul unor containere de tip BeanFactory și ApplicationContext [8].
O clasă BeanFactory este o clasă a cărei responsabilitate este să creeze și să elimine bean-uri.
Clasa ApplicationContext ce extinde BeanFactroy are responsabilitățile clasei precedente la care se mai adaugă câteva în plus:
are funcționalitate de interacțiune prin mesaje;
suportă modelul de gestionare a evenimentelor (poate notifica bean-uri);
poate încărca resurse (un fișier din sistem, o resursă localizată printr-un URL, resurse specificate în classpath) din aproape orice locație într-o modalitate transparentă.
În practică, mai întotdeauna se utilizează ApplicationContext.
IV.3. Bean Configuration
Spring utilizează termenul de bean pentru a se referi, în fișierele de configurare ale container-ul IoC, la obiecte specifice aplicației ale cărei dependințe le gestionează. Configurarea bean-urilor este o parte esențială a oricărei aplicații bazată pe framework-ul de Spring. Există două posibilități de configurare a container-ului de Spring : programatic (în codul aplicației) sau declarativ prin (fișiere de configurare XML). Fișierele de configurare utilizate că și definiții pentru bean-uri în container-ul Spring IoC sunt numite contextul aplicației Spring (Spring application context).
Bean – uri instanță unică (Singleton Bean) versus bean –uri prototip (Prototipe Beans) :
Spring permite configurarea de obiecte fie ca singură instanță în aplicație (singleton), fie ca multiplă instanță în aplicație (non-singleton).
Un obiect este numit singleton dacă nu există decât o singură instanță o clasei în intreaga aplicație. În Spring un obiect este considerat prototip dacă există mai mult de o instanță a clasei sale în aplicație.
Spring definește implicit bean-urile ca fiind singleton. Un bean singleton este de ajutor atunci când crearea de mai mult de o instanță este costisitoare în ceea ce privește timpul, procesorul sau încărcarea rețelei.
Conectarea bean-urilor (bean wiring) reprezintă explicitarea dependințelor bean-urilor cu implementările concrete în fișierele de configurare. Pentru că o aplicație bazată pe IoC presupune definirea dependințelor obiectelor în termeni de interfețe și clase abstracte, dependințele sunt setate în fișiere de configurare specificând implementările concrete.
IV.4. Conectarea automată (automatic wiring).
Spring permite conectarea automată a bean-urilor (în opoziție cu metoda declarării explicite a bean-urilor când fiecare obiect este configurat manual cu alte bean-uri).
Astfel, conectarea automată presupune să nu se expliciteze dependințele în fișierele de configurare și să-i revină framework-ului de Spring responsabilitatea de a găsi valori corespunzătoare pentru fiecare proprietate sau argument al constructorului.
După criteriile folosite la realizarea conectării automate se disting 4 modalități:
Prin nume: bean-ul este conectat prin numele proprietății. Spring folosește numele proprietăților ca să găsescă bean-uri în container care se potrivesc cu acele nume.
Prin tip: bean-ul este conectat prin tipul proprietății. Spring caută un bean pentru ficare propritate bazat pe tipul proprietății specificate.
Prin constructor: bean-ul este conectat prin constructor. Spring va căuta să găsescă un bean pentru fiecare argument al constructorului.
Prin autodectie: bean-ul este conectat prin constructor dacă nu are un constructor default fără argumente.
IV.5. Spring Web Services
Framework-ul de servicii Web de la Spring este un produs menit să creeze servicii Web orientate document. Framework-ul este destinat creării de serviici SOAP cu specificarea contractului înainte permițând crearea de servicii web folosind una sau mai multe metode pentru a manipula conținutul XML al documentelor. Acest produs este bazat pe Spring, ceea ce înseamnă că se pot utiliza conceptele de injectare a dependințelor ca parte integrală a serviciilor Web.
Funcționalități cheie ale framework-ului Spring-WS:
Mapări : cererile XML pot fi distribuite oricărui obiect depinzând de conținut (payload), de antet (Soap Action).
Suport pentru procesare XML: mesajele XML pot fi gestionate nu numai în modalitatea standard utilizând JAXP APIs (DOM, SAX și StAX), dar și cu JDOM, dom4j, XOM sau chiar tehnologii de marshalling.
Tehnologii Flexibile pentru marshalling de fișiere XML: modulul de transformare Obiect/XMLin Spring – WS suporta JAXB 1 și 2, XMLBeans, JiBX și XStream.
Suport pentru securitate de WS: WS-Security permite semnarea mesajelor SOAP, incriptarea și decriptarea lor sau autentificarea.
IV.5.1. Suportul Spring-WS pentru Client
Spring – WS asigură un pachet ce oferă suport pentru serviciile web pe partea de client, ceea ce permite accesarea pe baza de XML a serviciilor Web. De asemenea, facilitează utilizarea de mecanisme pentru a asigura conversia Obiect/XML astfel încât nivelul de tratare a serviciului va depinde doar de obiecte Java [21].
Pachetul org.springframework.ws.client.core furnizeză funcționalitatea de bază și conține șabloane pentru a simplifică utilizarea serviciilor Web. Clasa- șablon, principiul de design comun pentru Spring, este de a furniza metode utilitare pentru a executa operații comune, dar și pentru utilizări mai sofisticate cum ar fi să delege user-ului implementarea interfețelor de callback.
Șablonul pentru serviciul Web urmează același design. Clasele oferă metode utilitare variate pentru a trimite și a primi mesaje XML, pentru a realiza transformări de la obiecte la mesaje XML înainte de a trimite și permite multiple metode de transport.
Clasa WebServiceTemplate
Clasa WebServiceTemplate este clasa principală utilizată pe partea de client pentru a accesa servicii Web folosind framework-ul Spring-WS. Conține metode pentru trimiterea obiectelor Source și primește răspunsuri fie că Source, fie că și Result. În plus, poate serializa (marshall) obiecte în XML înainte de a le trimite pentru transport și poate deserializa (unmarshall)orice răspuns XML înapoi în obiect.
Transport
Clasa WebServiceTemplate folosește locatori de resursă URL că și destinație a mesajelor. Acest identificator de destinație specificat prin URL este rezolvat la nivelul obiectului WebServiceMessageSender care este responsabil de trimiterea mesajelor XML de-a lungul nivelului de transport. Se pot seta unul sau mai mulți senderi utilizând clasa WebServiceTemplate.
Factory de mesaje
Pe lângă obiectul responsabil de trimiterea mesajelor, clasa WebServiceTemplate are nevoie de un obiect factory de mesaje utilizate de serviciul Web. Există două astfel de obiecte factory de mesaje SOAP : SaajSoapMessageFactory and AxiomSoapMessageFactory.
Transmisia de Obiecte POJO
Pentru a facilita trimiterea de obiecte simple Java (POJO) clasa WebServiceTemplate dispune de un anumit număr de metode care primesc un Obiect că și argument reprezentând conținutul de date al mesajului.
Metoda marshalSendAndReceive(..) în clasa WebServiceTemplate deleagă conversia obiectului cerere la XML al unui obiect Marshaller și conversia răspunsului XML de la un obiect la un alt obiect Unmarshaller. Utilizând obiecte specializate pentru serializare/deserializare din/în obiect/XML, codul se poate ocupa de obiectul (informația) care este trimis sau/și să fie mai puțin responsabil de detaliile legate de cum este reprezentat în format XML.
IV.6. Suportul Spring pentru operațiile de serializare / deserializare Object/XML
Spring oferă suport pentru maparea conversiei Obiect/XML sau, pe scurt, mapare O/X. Maparea O/X este procesul de conversie a unui document XML la un obiect. Acest proces de conversie este cunoscut ca serializare XML (XML Marxhalling).
Un marshaller este responsabil de a serializa graph-ul unui obiect la un document XML. În modalitatea similară, un unmarshaller deserializeaza un document XML în graful unui obiect. Acest XML poate fi sub formă unui document în format DOM document (documentul XML este incaracat complet în memorie), un stream de intrare/ieșire sau un parser SAX (prelucrează elemente XML în mod serial declanșând evenimente la fiecare element).
Ușor de configurat : documentul de configurare a bean-urilor furnizează o modalitate simplă de a configura obiectele responsabile de operațiile de serializare/deserializare O/X fără a fi nevoie că aplicația să știe de specificul acestora (JAXB sau JiBX). Aceste obiecte utilizate pentru operațiile de serializare/deserializare pot fi configurate că orice alt bean în contextul aplicației. Mai mult, configurațiile bazate pe XML Schema sunt disponibile pentru numeroase obiecte ce realizează serializarea făcând astfel configurarea și mai simplă
Beneficii de utilizare a framework-ului Spring pentru realizarea mapărilor O/X :
Interfețe consistente : operațiile de mapare O/X sunt expuse în Spring prin 2 interfețe : Marshaller and Unmarshaller. Utilizarea acestor abstractizări permite o adaptare ușoară în cazul în care se dorește schimbare framework-urilor utilizate fără a fi necesară schimbarea claselor care se ocupă de serializare.
Ierarhie de Excepții consistentă : Spring furnizeză o conversie de excepții de la tipul specific utilizat de framework-ul ce realizează serializarea O/X la propria ierarhie de excepții folosind XmlMappingException ca și excepție-rădăcină.
La modul abstract Spring furnizează operațiile de serializare utilizând interfața
org.springframework.oxm.Marshaller.
De asemenea, pentru operația de deserializare, Spring folosește
interfataorg.springframework.oxm.Unmarshaller.
IV.2. JiBX
JiBX este un API utilizat pentru a realiza binding-ul de date XML la obiecte Java. Este foarte flexibil și permite fie să se pornească de la codul Java existent și să genereze XML Schema sau să pornească de la XML Schema și să genereze codul java necesar sau poate intermedia o legătură între codul Java existent și o schemă care reprezintă aceleași date. Este un API care are performanțe înalte față de alte opțiuni existente pe piață.
JiBX folosese documente în care se definește binding – ul pentru a specifica modul cum obiectele Java sunt convertite la sau din XML și combinate cu generarea de bytecode pentru a include codul de conversie direct în clase utilizate. Generarea bytecod-ului este făcută executând unul din componentele JiBX (compilatorul de binding) după ce clasele Java utilizate au fost compilate. Odată ce compilatorul de binding a rulat și clasele au fost reactualizate cu codul JiBX de binding se poate continua în mod normal cu pașii necesari pentru a ansambla aplicația în continuare.
O altă componentă a lui JiBX este binding-ul la runtime. Clasele modificate generate de compilatorul de binding folosesc această componentă de runtime pentru a realiza concret procesul de binding al obiectelor dintr-un document XML de intrare (numit deserializare (unmarshalling)) și pentru a genera document XML din obiecte (proces numit serializare (marshalling)).
Capitolul V. REALIZAREA PRACTICĂ A PROIECTULUI
Lucrarea de față are ca și obiective principale cunoașterea și prezentarea avantajelor utilizării serviciilor web în dezvoltarea aplicațiilor software. Acest fapt va fi evidențiat și concretizat în prezenta lucrare prin aplicarea practică a principiilor de comunicare utilizând astfel de servicii pentru prelucrarea și obținerea dateler necesare unei aplicații grafice. În speță, lucrarea de față se concentrează pe aspectele practice de realizare a unui client/server de servicii web și pe integrarea și aplicarea acestora la o aplicație grafică de sine stătătoare.
Și mai exact, obiectivul lucrării de față se ocupă în special de a crea suportul de comunicare dintre o aplicație desktop ca și client cu un web server ce furnizează servicii specializate pe monitorizariea și gestiunea unor locații de conținut media (video) și a conținutului acestora.
V.1. Specificațiile funcționale
Aplicația desktop prezentată în acesta lucare este destinată să afișeze informații referitoare la materialul video stocat la numite locații. Realizarea acestui obiectiv se face utilizând comunicare prin servicii web cu un server web ce furnizează astfel de servicii specifice.
La pornire utilizatorul se va identifica în sistem prin utilizarea unui nume și a unei parole. Accesul în sistem va fi posibil numai dacă utilizator este un utilizator înregistrat pentru a i se permite accesul la serviciile oferite.
Odată deschisă aplicația utilizatorul va putea să deschidă o componentă grafică care-i va permite să vizualizeze într-o structură arborescentă locațiile ce găzduiesc conținut video.
La selecția unei astfel de locații se va afișa în partea din dreapta a componenței grafice deschise conținutul de materiale video disponibile în formă tabelară. De asemenea, executarea de dublu-click pe una dintre locații va avea ca efect deschiderea unei alte componente grafice care va afișa separat și tot în formă tabelară continutul de material video al locației.
Conținutul de material video este prezentat sub forma unei înregistrări într-un tabel dintr-o componentă grafică și conține ca informații câteva din proprietatile (metadatele) specifice acestui material.
Tipurile de metadate de material video(film) afișat sunt : numele materialului, titlul, numele actorilor.
Astfel că obiectele cu care va interacționa user-ul și proprietățile ce le definesc pe acestea sunt:
Utilizator – ul:
Nume utilizator
Parola
Grupul de locații cu conținut media (Media Repository)
Numele
Lista de locații cu conținut media
Locația media (Media Location)
Nume
Tip
Status
Număr de continut video
Proprietati media
Nume
Titlu
Regizor
Actori
Astfel, din descrierea de mai sus se pot distinge practic 3 scenarii de utilizator posibile a fi întâlnite în practică:
Autentificare : Utilizatorul se autentifică folosid numele de utilizator și o parolă.
Vizualizare locații media : Utilizatorul vizualizează locațiile cu conținut media disponibile în sistem.
Vizualizare conținut media : Utilizatorul vizualizează conținutul media al unei locații ce găzduiește conținut media.
Fig. Interacțiuni posibile utilizator – sistem
Astfel se va urmări deci ca în aceste cazuri să se furnizeze suportul necesar de comunicare a aplicației cu server-ul web capabil de a oferi acest tip de servicii (autentificare, interogare locații cu conținut media, interogare material media).
V.2. Arhitectura componentelor sistemului
Arhitectura componentelor sistemului
Media Content Catalog GUI
Media Content Catalog GUI Components – reprezintă toată partea care se ocupă cu detaliile de implementare a componentelor grafice utilizate în aplicația GUI.
Web Service Client – reprezintă componenta care se ocupă cu asigurarea comunicării prin serviciu Web cu un server ce furnizează servicii web specializate pe specificul informației necesare clientului.
OXM – este partea care asigură de conversii obiect Java la document XML ce este necesar pentru realizarea comunicării prin mesaje SOAP.
Media Content Web Services Server
Server Web Services – responsabil de expunerea transparentă a serviciilor oferite și de transmiterea/delegarea procesării către serviciile oferite de un server specializat în astfel de operații.
OXM – este partea care asigură de conversii obiect Java la document XML ce este necesar pentru realizarea comunicării prin mesaje SOAP,
Media Server
Media Server Web Services – responsabil de expunerea transparentă a serviciilor de gestionare și monitorizare, de monitorizare și gestionare conținut media și de asigurarea procesării cererilor de acest tip.
Media Services Implementation – responsabil de procesarea efectivă a cererilor pentru gestionarea și monitorizarea conținutului media.
V.3. Modelul de date
Modelul de date este prezentat în figura de mai jos :
Modelul de date utilizat în aplicatie
În cele ce urmează se vor prezenta diagramele de clasă și o descriere a claselor ce compun modelul de date.
MediaContentRepository :
este clasa ce modelează un grup de locații și deci este reponsabilă cu menținerea unei liste cu locații asociate acestui grup.
Proprietăți :
id : idetificator unic de tip long ;
name : numele acestui grup de locații;
locations : lista de locații de conținut media asociat acestui grup;
MediaLocation :
este clasa ce modelează la nivel logic o locație cu conținut media
Proprietăți:
id : identificator unic;
name : numele atribuit acestei locații;
status : starea acestei locații (conectată sau deconectată);
tip : tipul acestei locații (ține de specificitatea sistemului)
MediaLocationStatus :
enumerare ce definește stări posibile ale unei locații de conținut media;
Domeniu valori : ONLINE, OFFLINE;
MediaLocationType :
enumerare ce definește tipurile de locații de conținut media;
Domeniu valori : CACHE, VIDEO_LIBRARY, MEDIA_SERVER;
MediaPropertyDefinition :
clasă ce modelează atribute ale unei proprietăți de material media (metadate de metadata). În sistem pentru un material video se pot defini anumite proprietăți în mod specializat. Astfel că atunci când se definește o astfel de proprietate (metadata) specială se asociază și o definiție a ei;
Proprietăți:
id : identificator unic;
name : numele definiției de proprietăți;
grupul : grupul de proprietăți din care face parte;
valueType: tipul de proprietate (dată sau timp);
displayMode : dacă valoarea este folosită sau nu la afișare sau editare;
PropertyValueType :
enumerare a modului de a afișa o anumită proprietate;
Domeniu valori : DATE, TIME;
PropertyDisplayMode :
enumerare a modului de a afișa o anumită proprietate;
Domeniu valori : VISIBLE, READ_ONLY ;
MediaPropertyValue :
este clasa care modelează valoarea unei metadate de continut media sau de locație;
Proprietăți:
id : indentificator unic;
value : valoarea metadatei conținutului media (tiltu film) sau a locației (status);
MediaServerCommunicator :
interfață ce stabilește operațiile ce pot fi efectuate către server-ul de servicii web;
patru operații sunt posibile în conformitate cu scenariile utilizator definite anterior;
această interfață este folosită de toate componentele GUI și reprezintă un mod de a decupla logica ce se ocupă de construirea componentelor grafice și de gestionarea acțiunilor utilizatorilor cu partea care se ocupă cu transmiterea și primirea de date la și de la server-ul web.
WSMediaServerCommunicator :
este clasa responsabilă să asigure concret partea de comunicare cu server-ul de servicii web.
cele patru operații ce necesită a fi efectuate de către componentele grafice pentru a transmite și a cere date sunt delegate mai departe unor obiecte specializate ce se ocupă de implementarea specifică a fiecăreia dintre cele patru operații.
că și membrii acestei clase sunt de fapt clase factory care sunt utilizate pentru a crea obiectele care să se ocupe de efectuarea specializată a operațiilor. Acești membri factrory sunt injectați de container-ul de Spring la initializarea acestuia și deci nu sunt instantiati concret de această clasă. Acest lucru face ca această clasă să aibă dependințe minime, ceea ce poate fi de mare ajutor la testarea acesteia.
V.4. Clientul de Web Services
V.4.1.Configurarea container-ului IoC de la Spring
V.4.1.1.Configurarea bean – urilor
Prin configurarea bean-urilor se urmărește realizarea unui mod de a declara dependințele între obiectele utilizate în aplicație și injectarea acestora atunci când este nevoie de obiect în applicatie cerând-o de la container-ul de Ioc de la Spring.
Configurarea bean -urilor pentru aplicația prezentată se face în mod declarativ prin fișiere de configurare XML numite și fișiere de definiție de bean-uri. Fișiere de propritati și fișierele de configurare XML pentru definirea bean-urilor în container-ul de IoC de la Spring poartă denumirea de contextul aplicației Spring.
Fișierul de configurare a bean-urilor are ca elment rădăcină intotdeauna un element
Fiecare element conține toată informația necesară container-ului pentru a configura un obiect în IoC, pentru a-i gestiona ciclul de viață și a-i crea dependențele necesare.
În aplicație, fișierele de configurare a container-ului de Spring este localizat ca în Figura 13.
Fișierul application-context reprezintă fișierul de configurare a contextului aplicației Spring și conține:
<import resource="spring-webservice-client.xml"/>
<import resource="user-services.xml"/>
<bean class="org.springframework.beans.factory.config
.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:application.properties</value>
</property>
</bean>
Fișiere de configurare container IoC Spring
Se poate observa că fișierul de configurare utilizeza pentru configurare două fișiere de definiție a bean-urilor : spring-webservice-client.xml, user-services.xml. De asemenea, fișierul încarcă și un fișier de proprietăți specifice (URI – ul server-ului de servicii web) aplicației : application.properties.
Pentru exemplificarea modului de configurare a bean-urile voi prezenta în continuare scurte fragmente cu definițiile bean-urilor celor mai importante din fișier-ul de configurare spring-webservice-client al modului client responsabil de comunicare prin servicii web și modul în care se face încarcarea fișierului cu proprietăți specializate (ex :URI web server-ului de servicii web) :
<bean class="org.springframework.beans.factory.config
.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:application.properties</value>
</property>
</bean>
Fiecare bean element conține minim două atribute :
id : numele prin care obiectul este identificat în container ca și bean distinct;
class : clasa concretă a obiectului.
Bean – ul WebServiceTemplate este clasa principală utilizată pe partea de client pentru a accesa servicii Web folosind framework-ul Spring-WS.
Este responsabilă de trimiterea și primirea mesajelor SOAP la și de la server-ul de servicii web cu care comunică.
Pentru a configura acest obiect este nevoie să i se seteze două proprietăți importante : destinația mesajului cu valoare citită din fișierul de proprietăți specializate application.properties (defaultUri ="${server.uri}) și o clasă care să construiască mesajele SOAP.
<bean id="clientws.webServiceTemplate"
class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="defaultUri" value="${server.uri}"/>
<property name="messageFactory">
<bean class="org.springframework.ws.soap.axiom
.AxiomSoapMessageFactory"/>
</property>
</bean>
Fragmentul de mai jos definește un bean simplu ce este asociat obiectului SessionIdContainerImpl responsabil de reținerea id-ului sesiunii asociate clientului după o operație de autentificare încheiată cu succes:
<beanid="clientws.sessionIdContainer"
class="com.mcc.client.transport.clientws.impl.SessionIdContainerImpl"/>
Pentru a înțelege următoarea structură de bean-uri cu legăturile necesare între ele, voi considera că și exemplu clasa LoginOperation. Această clasă este responsabilă de tratarea requestului/răspunsului la operațiunea de autentificare din cadrul aplicației a cărei implementare este prezentată în continuare:
package com.mcc.client.transport.clientws;
import org.springframework.ws.client.core.WebServiceOperations;
import com.mcc.client.transport.User;
import com.mcc.container.SetFromSpring;
publicclass LoginOperation {
private WebServiceOperations wsOperations;
private SessionIdContainer sessionIdContainer;
User login(String username, String password) {
LoginRequest request = new LoginRequest();
request.setUsername(username);
request.setPassword(password);
LoginResponse response = (LoginResponse) wsOperations
.marshalSendAndReceive(request);
User user = response.getUser();
sessionIdContainer.setSessionId(user.getSessionId());
return user;
}
@SetFromSpring
publicvoid setWsOperations(WebServiceOperations wsTemplate) {
this.wsOperations = wsTemplate;
}
@SetFromSpring
publicvoid setSessionIdContainer (SessionIdContainer sessionIdContainer) {
this.sessionIdContainer = sessionIdContainer;
}
}
Următoarea diagramă exprimă structura dependințelor necesare obiectului LoginOperation pentru a fi complet configurat la runtime și structura care urmează să fie descrisă în fișierul de configure a bean-urilor:
Structura dependințelor obiectului LoginOperation.
În fragmentul de mai jos se setează bean – ul corepunzător obiectului LoginOperation. Bean- ul este definit ca fiind de tip prototipe pentru a comunica faptul că acest obiect nu este un singleton și mai concret, indică faptul că la invocări repetate ale container-ului pentru a obține acest obiect acesta va returna instanțe diferite ale clasei specificate.
De asemenea, prin elementele property se realizeză setarea (setter injection) proprietăților obiectului LoginOperation identificate prin numele lor așa cum sunt explicitate în definiția clasei.
Atributul reutilizat la fiecare element property indică faptul că se dorește setarea proprietăților prin referirea altor bean-uri definite în fișier-ul de configurare. Deci elementul ref este folosit ca să se refere la alt obiect (clientws.sessionIdContainer, clientws.wstemplate.login) definit în altă parte a fișierului XML de configurare. Această definiție exprimă, de fapt, exact aceea că Spring trebuie să instantieze un obiect SessionIdContainerImpl si un altul special – vom vedea în cele ce urmează de ce – WebServiceTemplate ori de câte ori este nevoie să creeze o instanță de LoginOperation.
<bean id="clientws.operation.login" scope="prototype"
class="com.mcc.client.transport.clientws.LoginOperation">
<property name="sessionIdContainer" ref="clientws.sessionIdContainer"/>
<property name="wsOperations" ref="clientws.wstemplate.login"/>
</bean>
Următoarea declarație definește setarea unui bean care se află într-o relație de moștenire de configurație de la un altul definit în altă parte a fișierului de configurare. În cazul de față, declarația bean-ului identificat cu id- ul clientws.wstemplate.login moștenește definiția bean-ului identificat prin atributul parent. Prin moștenirea definiției un bean copil poate să suprascrie sau să adauge valori după necesitate [22].
În definiția de mai jos, bean-ul setează proprietățile marshaller și unmarshaller ale bean-ului părinte. La rândul lor, obiectele utilizate, pentru a fi referite de proprietățile marshaller și unmarshaller ale obiectului WebServiceTemplate, sunt și ele configurate setându-li-se proprietatea targetClass cu obiectele corespunzătoare.
<bean id="clientws.wstemplate.login"parent="clientws.webServiceTemplate"
scope="prototype">
<property name="marshaller">
<bean class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass"
value="com.mcc.client.transport.clientws.LoginRequest"/>
</bean>
</property>
<property name="unmarshaller">
<bean class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass"
value="com.mcc.client.transport.clientws.LoginResponse"/>
</bean>
</property>
</bean>
În final, revenind la structura definită în Figura 14 container-ul de Spring la momentul când i se cere să returneze un obiect LoginOperation trebuie să creeze toate obiectele referite de acesta, să le seteze la rândul lor cu proprietățile necesare (care pot fi alte dependințe) și apoi trebuie să le conecteze între ele așa cum sunt specificate dependințele în fișierul de configurare XML.
V.4.1.2. Suport Java pentru interacțiune cu container-ul IoC de la Spring
Container-ul IoC de la Spring este numit un factory de bean-uri. Spring dispune de mai multe factory-uri și toate o implementare a org.springframework.beans.factory. BeanFactory. La modul general, un factory de bean-uri creează obiecte, le conectează între ele și gestionează ciclul lor de viață. Pentru a porni container-ul este nevoie să se creeze și să se configureze un obiect specializat de factory de bean-uri. În cazul de față se va utiliza.ClassPathXmlApplicationContext o subinterfata din pachetul org.springframework.context.support a lui BeanFactory care citește fișiere de configurare XML setate în classpath.
Înainte însă de a putea porni container-ul pentru a obține obiectele dorite a mai fost nevoie de crearea unor clase factory destinate creării de obiecte necesare aplicației prin cererea lor de la container-ul de Spring într-o modalitate care să asigure o cât mai mare izolare a codului față de obiecte specifice acestui Container.
Astfel clasele din pachetul container al proiectului oferă suportul necesar pentrua realiza acest lucru – accesarea de obiecte creeate de contaionerul IoC de la Spring.
Clasa SpringFactoryBean (anexă[1]) este o clasă cu o responsabilitate specială. Ea este o clasă de tip factory bean. Un factory bean este de fapt un bean în interiorul container-ului IoC care produce alte obiecte. De obicei container-ul de IoC este un factory de bean-uri ce instanțiază și gestionează bean-uri în timp ce un factory beans este un bean obișnuit gestionat de container-ul IoC de la Spring.
Astfel pentru a crea un factory bean – ul din aplicație clasa SpringFactoryBean implementează interfața beans.factory.FactoryBean :
public interface FactoryBean {
Object getObject() throws Exception;
Class getObjectType();
boolean isSingleton();
}
Metoda getObject()returnează obiectul creat de această clasă factory. Container-ul cheamă automat această metodă când factory bean-ul e accesat. Metoda isSingleton() determină dacă obiectul returnat e un singleton sau nu. Metoda getObjectType() determină tipul obiectului creat (sau null dacă nu este cunoscut).
Astfel clasa BeanObjectFactory este clasa utilizată pentru pentru a cere obiecte de la container-ul de Spring prin apelul metodei getBean() având ca și parametru numele sau id-ul obiectului necesar. Cu toate acestea, când un factory bean este referit de alt bean în container sau de codul aplicației prin apelul metodei getBean() container-ul nu returnează o instanță de factory bean. În schimb, acesta returnează obiectul pe care factory bean-ul îl produce.
package com.mcc.container.impl;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.mcc.container.Factory;
import com.mcc.container.FactoryException;
@SuppressWarnings("unchecked")
class BeanObjectFactory implements Factory, ApplicationContextAware {
private String type;
private ApplicationContext applicationContext;
public Object create () throws FactoryException {
try {
return applicationContext.getBean (type);
}
catch (BeansException exc) {
throw new FactoryException (exc);
}
}
@SetFromSpring
public void setType (String type) {
this.type = type;
}
public void setApplicationContext (ApplicationContext theApplicationContext) {
this.applicationContext = theApplicationContext;
}
}
Proprietatea type este utilizată pentru a reține tipul obiectului dorit a fi instanțiat. Această proprietate va fi setată de container-ul de Spring pe baza modului de explicitare a dependințelor din fișierul de configurarea al container-ului de Spring, fapt care este marcat de utilizarea adnotării @SetFromSpring.
În următorul fragment din fișierul de definiție a bean-urilor se va exemplifica modul în care este utilizată clasa BeanObjectFactory pentru a fi folosită la nivelul aplicației:
<bean id="serverCommunicator"
class="com.mcc.client.transport.clientws.WSMediaServerCommunicator">
<property name="getMediaObjectsOperationFactory">
<bean class="com.mcc.container.impl.BeanObjectFactory">
<property name="type" value="clientws.operation
.getMediaContentObjects"/>
</bean>
</property>
<property name="loginOperationFactory">
<bean class="com.mcc.container.impl.BeanObjectFactory">
<property name="type" value="clientws.operation.login"/>
</bean>
</property>
…
</bean>
În acest fragment se poate observa că obiectului WSMediaServerCommunicator i se setează proprietatea loginOperationFactory ca fiind un obiect de tipul BeanObjectFactory a cărui proprietate type este setată ca având valoarea unui alt bean din fișierul de definiție identificat ca fiind clientws.operation.login adică un obiect de tip LoginOperation. Aceasta înseamnă că în aplicație când se va apela loginOperationFactory.create(), acesta va returna un obiect de tip LoginOperation.
Și în final, pentru a porni container-ul este nevoie să se creeze și să se configureze un obiect specializat de factory de bean-uri. În cazul de față se va utiliza org.springframework.context.support.ClassPathXmlApplicationContext o subinterfata a lui BeanFactory care citește fișiere de configurare XML setate în classpath:
publicstaticvoid main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"spring/application-context.xml");
…
}
V.4.2. Realizarea conversiilor XML/Object
Pentru relizarea transformărilor Obiect la XML și invers necesară la comunicare clientului de servicii web cu server-ul de servicii web s-a adoptat utilizarea unui API numit JiBX.
Pentru a defini regulile necesare realizării conversiei obiectelor Java la XML și invers se folosesc niște fișiere de definire a conversiei (binding definition) speciale sub forma unor documente XML. Compilatorul de conversie a lui JiBX primește unul sau mai multe fișiere de conversie ca și intrare împreună cu fișierele sursă Java. Apoi acesta compilează aceste fișiere de definiție a conversiei generând fișiere Java byte code care în final sunt adăugate la fișierele sursă ale aplicației. Odată ce fișierele aplicației au fost completate cu fișierele compilate de JiBX ce conțin codul ce definește conversiile necesare aplicația este pregătită să le utilizeze la runtime.
Se pot adaugă oricâte fișiere de definite pentru realizarea conversiei pentru același set de clase sau pentru clase diferite. Compilatorul de conversie generează automat cod pentru toate conversiile definite și chiar reutilizeza codul adăugat între asocieri ori de câte ori este posibil. Totuși de fiecare dată când se execută operații de serializare/deserializare (marshall/unmarshall) a unui document XML trebuie stabilit concret ce definiție de conversie se va utiliza pentru acel document. Fiecare definiție este independentă de celelalte și deci nu se pot schimba definiții pentru același document.
În cele ce urmează se va exemplifica modul de folosire a fișierelor de definiție a conversiei obiectelor Java în XML utilizate în aplicație de către client-ul/server-ul de web services pentru transmisia mesajelor SOAP. Voi explica pornind de la următorul mesaj dorit a fi transmis de către aplicație prin clientul de web services către server-ul de servicii Web pentru operațiunea de autentificare:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<mcc:LoginRequest xmlns:mcc="http://www.mcc.com/mcc/ws/schemas"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi="http://www.w3.org/2001/XMLSchema-instance">
<mcc:username>user1</mcc:username>
<mcc:password>operator</mcc:password>
</mcc:LoginRequest>
</soapenv:Body>
</soapenv:Envelope>
Mesajul conține în body – ul său serializarea unui obiect LoginRequest care are următoarea clasă Java:
package com.mcc.client.transport.clientws;
class LoginRequest {
@SuppressWarnings("unused")
private String username;
@SuppressWarnings("unused")
private String password;
void setUsername(String username) {
this.username = username;
}
void setPassword(String password) {
this.password = password;
}
}
Analiză mesajului conținut de elementul <Body> scoate în evidență următoarele elemente:
LoginRequest – elementul rădăcină al mesajului;
username – elementul care conține numele utilizatorului;
password – elementul care conține parola de autentificare;
Analiză clasei Java ce se dorește a fi serializată definește următoarele:
LoginRequest – numele clasei;
username – proprietate destina sa stocheze numele utilizatorului;
password – parola de autentificare utilizată pentru autentificare;
Pentru operația de serializare/deserializare se dorește definirea corespondențelor între proprietățile clasei obiectului LoginRequest și cele ale elementelor mesajului SOAP ce se dorește transmis: Pentru acesta JiBX utilizeza aceste fișiere de conversie ca și în exemplul următor (anexa [2]) :
<?xmlversion="1.0"encoding="UTF-8"?>
<binding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="binding.xsd">
<namespace uri="http://www.mcc.com/mcc/ws/schemas"
prefix="mcc" default="all"/>
<mapping name="LoginRequest"
class="com.mcc.client.transport.wsclient.LoginRequest">
<value name="username" field="username"/>
<value name="password" field="password"/>
</mapping>
…
</binding>
Acest document ce conține definiția conversiei obiectului Java LoginRequest în și din XML este un document XML cu următoarele elemente:
elementul <binding> : este elementul rădăcină al unui fișier de binding. Aici se definesc caracteristici pentru întreaga conversie.
elementul <namespace> : elementele namespace sunt folosite pentru a asigura restricții referitoare la faptul că spațiile de nume cu același prefix nu pot fi definite în același context și nu se pot defini două spații de nume care au valori implicite aflate în contradicție în același context ((i.e., două spații de nume care au default="elements" sau default="all") .
elementul <namespace> definește un spațiu de nume folosit în documentul XML. Fiecare spațiu de nume folosit în cadrul documentului trebuie să fie definit utilizând unul din aceste elemente. Când se serializează la XML definiile spațiilor de nume incluse în fișierul de conversie sunt adăugate automat la elemetele XML corespunzătoare: <mcc:username>, <mcc:password>.
elementul <mapping> : este folosit pentru a relaționa elementul nume la o clasă particulară (elementul LoginRequest este relaționat la clasa java LoginRequest). JiBX folosește această asociere implicit atât pentru operația de serializare cât și pentru cea de deserializare
elementul <value> : element folosit pentru a gestiona componente text. În XML compenenta de text poate fi un atribut, element, date, caractere. În Java componenta text poate fi valoarea oricărei primitive sau tip de obiect care are definită o conversie de la și la o valoare String.
În proiectul prezentat fișierele de definire a conversiilor sunt localizate în pachetul /src/main/jibx și trebuie avută grijă ca la momentul compilării proiectului să ruleze și compilatorul de conversii JiBX pentru a avea incluse și sursele necesare realizării conversiilor O/X.
Fișierul bindings.xml conține specificate toate din aceeași locație cu fișierele de definire a conversiilor O/X cuprinde o listă cu toate fișierele de definiție a conversiilor. Compilatorul va citi acest fișier și va rula fiecare fișier de definiție a conversiilor incluse în acest fișier.
În aplicația de față, compilatorul de jibx este setat să ruleze în fișierul de build al lui v maven cu următoarea declarație:
<plugin>
<groupId>org.jibx</groupId>
<artifactId>jibx-maven-plugin</artifactId>
<version>1.2.5</version>
<configuration>
<schemaBindingDirectory>src/main/jibx</schemaBindingDirectory>
<includes>
<includes>bindings.xml</includes>
</includes>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<id>jibx-bindings</id>
<phase>process-classes</phase>
<goals>
<goal>bind</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
V.4.2. Scenarii de execuție
În cele ce urmează vom detalia câteva din scenariile de aplicație prezentate la descrierea proiectului pentru a descrie modul de integrare și utilizare a clientului (a comunicării) de servicii Web în cadrul aplicației.
V4.2.1. Autentificare client.
În vederea realizării acestui scenariu, la pornirea aplicației este afișat dialog-ul de Login ce conține două controale în care utilizatorul-ul poate să introducă date de autentificare. Astfel, acesta trebuie să adauge numele și parola necesare pentru realizare autentificării de acces în aplicație. După introducerea datelor acesta trebuie să apese pe butonul Login al dialogului de autentificare. Dacă autentificarea a reușit, atunci user-ul capătă acces la sistem; dacă nu, atunci un mesaj de eroare va fi afișat pe dilog-ul de Login.
Structura de obiecte ce sunt implicate în acest scenariu este prezentată în următoarea diagramă:
Diagrama de obiecte implicate la realizarea operațiunii de autentificare la accesul în aplicație.
După cum se poate vedea, structura de obiecte este una foarte simplă și asta se datorează în special utilizării Inversiunii de Control pentru injectarea dependințelor obiectelor implicate în realizarea aceastei operațiuni.
Clasele sunt create ca să se refere la dependințele lor numai prin interfețe urmând că la runtime să se injecteze dependințele concrete prin metodele factoy explicate și apelând la container-ul IoC de la Spring pentru creearea lor.
Minimizarea numărului de dependințe între obiecte are avantaje foarte mari în ceea ce privește simplitatea design-ului, efortul de întreținere, scalabilitatea sistemului și ușurința de integrare a testelor unitare acest tip de clase. Modul de realizare a operațiunii de autentificare este ilustrat în diagrama de secvență următoare:
Diagrama de secvență pentru operația de autentificare.
V.4.2.2.Vizualizare conținut media disponibil pe una dintre locațiile afișate.
Pentru a vizualiza conținutul media disponibil la o anumită locație, utilizatorul se folosește de componenta Media Location Navigator ce are afișate locațiile disponibile în sistem.
Apoi selectează cu mouse-ul una dintre locațiile afișate. În partea din dreapta a navigatorului de locații i se va afișa sub formă tabelară conținutul media al locației selectate.
Diagrama de obiecte implicate în reaizarea acestei operațiuni este prezentată în figura următoare:
Diagrama obiectelor implicate la vizualizarea conținutului media al unei locații selectate.
Se poate observa că indiferent de operația ce este necesară design-ul ierarhiei de obiecte rămâne la fel de simplu și că orice astfel de operație necesară pentru a transmite sau a cere informație de către sau pentru interfața grafică, poate fi modelată utilizând acest model.
Diagrama interacțiuilor în cazul acesta sunt prezentate în cele ce urmează in Figura 18, 19 :
Diagrama de secvența o operațiilor cerere/răspuns ale clientului de servicii web
Diagrama de secvența pentru operația de vizualizare conținutului media a unei locații selectate
V.5. Server-ul de servicii Web
În partea a doua a proiectului se va descrie modul de realizare a suportului necesar pentru a crea servicile web utilizate de aplicația client.
Acest lucru presupune realizarea unei aplicații web în care server-ul va furniza serviciile (Services Enpoints) necesare clientului prezentat în prima parte. Server-ul care furnizează serviciile Web va fi accesibil pe baza adresei de URL a serviciului.
Serviciile oferite de server-ul furnizor de servicii vor fi servicii de tip SOAP (Simple Object Access Protocol), în care atât cererile cât și răspunsurile au forma unor mesaje SOAP (documente XML cu un anumit format) transmise tot peste HTTP. În astfel de servicii furnizorul expune și o descriere a interfeței API sub forma unui document WSDL (Web Service Description Language), care este tot XML și poate fi prelucrat de client. Clientul trebuie sã cunoascã metodele oferite de cãtre un “Service Endpoint”, pe care le poate află din descrierea WSDL.
Pentru implementarea serviciilor web utilizate de către aplicația client se va folosi tot suportul pe care Spring îl oferă pentru implementarea de servicii web și de asemenea container-ul de IoC de la Spring.
Crearea unui serviciu Web poate porni de la un WSDL existent (top-down, contract first) sau de la un program sursã Java (bottom-up, contract last) din care se creeazã apoi WSDL-ul.
Implementarea care pornește de la WSDL se mai numește și “contract-first” pentru cã acest WSDL este pivit ca un contract între furnizorul serviciului și clientul serviciului.
În cadrul acestui tip de implementare furnizorul de servicii (“Service Endpoint”) expune o interfatã cu serviciile oferite clientului, sub forma unui fișier WSDL care descrie operațiile oferite de furnizorul de servicii, fișier folosit de client pentru a genera cereri la serviciile oferite. Fișierul WSDL este o modalitate de transmitere a interfeței server-ului cãtre aplicația client.
În cazul de față se va alege abordarea de a definire mai întâi a fișierului WSDL.
În cele ce urmează, se va exemplifica crearea unui serviciu web de autentificare necesar aplicației client.
V.5.1. Crearea documentului WSDL de descriere a serviciului.
Pentru a crea un serviciu prin metoda contract – first este necesară descrierea parametrilor serviciului în și a tipurilor returnate folosind XML Schema. Apoi folosid schema se va genera documentul WSDL pentru a o descriere a serviciului
Pentru a crea fișierul WSDL în care este descris serviciul de autentificare se va porni de la descrierea obiectului ce conține informația de autentificare folosit în aplicație adică a obiectului User ca si în fragmentul următor :
<?xmlversion="1.0"encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.mcc.com/mcc/ws/schemas"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.mcc.com/mcc/ws/schemas">
–
<xs:complexType name="User">
<xs:sequence>
<xs:element name="id" type="xs:int"></xs:element>
<xs:element name="username" type="xs:string"></xs:element>
<xs:element name="sessionid" type="xs:string"></xs:element>
</xs:sequence>
<xs:complexType>
</xs:schema>
Apoi se vor defini în aceeași XML schemă tipul request-ului și al răspunsului folosit de serviciul de autentificare ca și în fragmentul următor:
<?xmlversion="1.0"encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.mcc.com/mcc/ws/schemas"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.mcc.com/mcc/ws/schemas">
–
<xs:element name="LoginRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="username" type="xs:string"></xs:element>
<xs:element name="password" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="LoginResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="User" type="tns:User"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
V.5.2. Conversia obiectelor Java din si în documente XML
Ca și în cazul clientului, această etapă este rezolvată prin utilizarea framework-ului JiBX și a fișierelor de configurare așa cum s-a explicat în cadrul descrierii anterioare a clientului de servicii Web utilizat de aplicație pentru a cere și trimite date de la și la server-ul furnizor de servicii.(V.4.2)
V.5.3. Definirea Serviciului
În continuare, se trece la implementarea serviciului. Toate obiectele care se ocupă de procesarea serviciului solicitat implementează interfața MessageProcessorExecutor :
package com.mcc.serverws.support;
interface MessageProcessorExecutor {
Object execute(Object requestObject, String sessionId) throws Exception;
}
Acesta conține o singură metodă destinată să proceseze cererea care are ca și parametri cererea și un identificator de sesiune.
Implementarea acestei interfețe pentru serviciul de autenticare este:
package com.mcc.serverws.support;
import com.mcc.container.SetFromSpring;
import com.mcc.serverws.MediaServer;
public class LoginExecutor implements MessageProcessorExecutor {
private MediaServer wsServer;
public Object execute(Object request, String sessionId) throws Exception {
LoginResponse response = (LoginResponse) wsServer
.service((Request) request);
return response;
}
@SetFromSpring
public void setWsServer(MediaServer wsServer) {
this.wsServer = wsServer;
}
}
În cazul de față procesarea request-ului constă în delegarea spre procesare la un alt serviciu oferit de obiectul MediaServer. După terminarea procesării request-ul MediaServer va returna un obiect ce constitue răspunsul (LoginResponse).
V.5.4. Creearea punctului de acces al serviciului (Service Endpoint)
Un endpoint al unui serviciu este componenta care se ocupă de procesarea răspunsurilor și a cererilor. De fapt, Servlet-ul de Spring interceptează cererile SOAP pentru un URL definit și le redirectioneza la un endpoint pentru procesare.
În cele ce urmează este definit MessageProcessorEndpoint endpoint-ul părinte utilizat în aplicație. Se va arăta ulterior, la configurarea container-ului de Spring, că acest endpoint este folosit că bază pentru endpoint-urile specifice asociate serviciilor oferite:
package com.mcc.serverws.support;
import java.io.IOException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.MessageEndpoint;
import org.springframework.ws.support.MarshallingUtils;
import com.mcc.container.Factory;
import com.mcc.container.SetFromSpring;
class MessageProcessorEndpoint implements MessageEndpoint {
private Factory<MessageProcessorExecutor> executorFactory;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
@SetFromSpring
public void setExecutorFactory(Factory<MessageProcessorExecutor>
executorFactory) {
this.executorFactory = executorFactory;
}
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
@SetFromSpring
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void invoke(MessageContext messageContext) throws Exception {
…
Object responseObject = execute(requestObject, sessionId);
if (responseObject == null) {
return;
}
WebServiceMessage response = messageContext.getResponse();
marshalResponse(responseObject, response);
}
…
privateObject execute (Object requestObject, String sessionId)
throwsException {
…
returnexecutor.execute(requestObject, sessionId);
}
}
Clasa definește două proprietăți menite a stoca referințe la obiecte care se ocupă de conversia obiect Java la document XML și invers.
De asemenea metodă de factory este destinată a fi folosită la runtime pentru a seta obiectu specializat în procesarea tipului de cerere utilizând container-ul de IoC de la Spring și în funcție de tipul endpoint-ului.
Se poate observa că metoda invoke care primește ca și parametru un obiect și care încapsulează atât cererea cât și răspunsul va apela la un moment dat la metoda execute pe obiectul specific care va trebui să se ocupe de procesarea specifică a request-ului (LoginRequest).
Configurarea dependințelor acestui obiect se face în fișier-ul de configurare al container-ului de Spring. Modul în care se realizeză aceste definiții de bean-uri a fost prezentat mai amplu în capitolul destinat realizării clientului de servicii web.
V.5.5. Configurarea Container-ului de Spring
Pentru a profita de capabilitățile oferite atât pentru injectarea dependințelor dintre obiecte câte și pentru generearea fișierului de descriere a serviciilor trebuie realizat un fișier de configurare a container-ului de Spring.
Un fragment din acesta este prezentat în continuare pentru a evidenția cum sunt configurate obiectele în cazul serviciului de autentificare:
<!– PUBLISHING WSDL –>
<bean id="serverws"
class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition">
<description>
Defines the WS services. See the Spring WebServices documentation.
</description>
<property name="builder">
<bean class="org.springframework.ws.wsdl.wsdl11.builder.
XsdBasedSoap11Wsdl4jDefinitionBuilder">
<property name="schema" value="/WEB-INF/ws-schema.xsd"/>
<property name="portTypeName" value="MediaContentServer"/>
<property name="locationUri" value="/serverws"/>
<property name="targetNamespace" value="http://www.mcc.com/">
</property>
</bean>
</property>
</bean>
<bean class="org.springframework.ws.server.endpoint.mapping.
PayloadRootQNameEndpointMapping ">
<description>
This object maps WS requests to endpoints implementing them, as
described in the Spring WebServices documentation.
</description>
<property name="mappings">
<props>
<prop key="{http://www.mcc.com/mcc/ws/schemas}
GetMediaContentLocationsRequest">
ws.endpoints.getMediaContentLocations
</prop>
<prop key="{http://www.mcc.com/mcc/ws/schemas}LoginRequest">
ws.endpoints.login
</prop>
…
<!– ENDPOINT Definition –>
<bean id="webservice.oxmEndpoint" abstract="true"
class="com.mcc.serverws.support.MessageProcessorEndpoint">
</bean>
<bean id="oxm.Marshaller" abstract="true"
class="org.springframework.oxm.jibx.JibxMarshaller"/>
<bean id="webservice.endpoints.login" parent="webservice.oxmEndpoint">
<propert yname="unmarshaller">
<bean parent="oxm.Marshaller">
<property name="targetClass"
value="com.mcc.serverws.messages.LoginRequest"/>
</bean>
</property>
<propertyname="marshaller">
<bean parent="oxm.Marshaller">
<property name="targetClass"
value="com.mcc.serverws.messages.LoginResponse"/>
</bean>
</property>
<property name="executorFactory">
<bean class="com.mcc.container.impl.BeanObjectFactory">
<property name="type" value="webservice.executors.login"/>
</bean>
</property>
</bean>
<!– EXECUTORs –>
<bean id="webservice.executors.login" scope="prototype"
class="com.mcc.serverws.support.LoginExecutort">
<property name="mediaServer" ref="mediaServer"/>
</bean>
Utilizarea DefaultWsdl11Definition face posibilă generarea automată a fișier-ului WSDL. Spring va folosi definiția schemei XML specificată în proprietate numită schema precum și portType, serviceName și LocationUri pentru a genera fișierul WSDL prima oară când este cerut.
Se poate de asemenea observa că la fiecare endpoint se atașează și un procesator al conversiilor Obiect la XML și invers fiind un obiect specific aparținând framework-ului de convesii O/X de la JiBX. Acesta va folosi fisierele de definire a convesiilor pentru tipul de request/răspuns pentru a realiza convesiie necesare așa cum s-a descris în secțiunea clientului de servicii web.
Obiectul identificat ca și bean prin id-ul webservice.endpoints.login reprezintă configurarea endpointului specific pentru serviciul de autentificare și moștenește configurarea enpointului general webservice.oxmEndpoint acesta fiind declarat ca și abstract și de asemenea se observă că setează obiectele LoginRequest și LoginResponse spre a fi utilizate pentru realizarea conversiilor în și de la obiect la XML.
V.5.6. Configurarea fisierului web.xml.
<?xmlversion="1.0"encoding="UTF-8"?>
<web-app
xmlns=http://java.sun.com/xml/ns/j2ee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>MCCServer</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF /spring-webservice-config.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context
.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http
.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
contextConfigLocation : explicitează fișierul în care se găsesc toate fișierele de definire a beab-urilor necesare pentru container-ul de Spring.
ContextLoaderListener : încarcă aplicația Spring la startarea aplicației folosind fișierul de configurare specificat de contextConfigLocation.
MessageDispatcherServlet : Servlet-ul de servicii Wen care interceptează cererile HTTP
V.5.7. Instalarea aplicației.
Odată configurarea terminată se poate deploy-ui aplicația pe un application server. Pentru server-ul de față am folosit un OC4J care este container-ul J2EE de la Oracle.
Accesând http://localhost:8888/mcc-server/serverws/serverws.wsdl s-a obtinut fișierul WSDL din anexa [3].
Concluzii
Arhitectura orientată pe servicii (SOA) este o abordare obișnuită pentru dezvoltarea aplicațiilor Enterprise unde sistemele încapsulează funcționalitatea ca și servicii Web interoperabile. Principiile sale de realizare sunt reutilizarea, modularitatea, interoperabilitatea și separarea pe componente (servicii).
Serviciile Web se referă la specificarea tehnologiilor în timp ce SOA este un principiu (un stil) de proiectare a software-ului. La modul și mai concret spus, WSDL-ul ce descrie serviciile Web poate fi privit ca fiind standardul de definiție conformă cu SOA, aici fiind punctul comun unde serviciile Web și SOA se unesc la modul fundamental.
În concluzie, serviciul Web reprezintă o realizare a SOA. Este important de reținut că SOA reprezintă un model arhitectural, care este independent de orice platformă de tehnologie și servicile Web reprezintă cea mai populară implementare a SOA.
Aplicarea SOA în lucrarea de față are ca și scop să asigure un nivel de servicii și funcționalități pentru o aplicație grafică. În afară de acestea, interfața cu utilizatorul este independentă de nivelul de servicii. Totul se reduce la principiul fundamental de separare a responsabilităților (o versiune mai generală a separării nivelului de prezentare de cel de date).
În lucrarea de față, arhitectura SOA a fost implementată într-o formă relativ simplă, client-ul (interfața grafică) utilizând servicii Web specializate într-un anumit domeniu – gestionare conținut media. Totuși, clienții mai complecși pot expune funcționalități ce presupun accesarea de servicii cât mai diverse distribuite în diferite noduri din rețea în funcție de specificațiile aplicației.
Folosind SOA, această problema poate fi rezolvată foarte simplu pentru că SOA are capacitatea de a furniza mai multe tipuri de servicii. Unele servicii pot să ofere logică la nivel de aplicație (application-level logic) , respectiv, menținerea sesiunii utilizator active, iar alte servicii furnizează logică de bussines (logică de procesare folosită de toți utilizatorii unui sistem).
Deci, scopul aplicării SOA a fost să asigure decuplarea datelor și functionalitatilor de interfață grafică astfel încât, de exemplu, datele și/sau funcționalitățile să poată fi distribuite, într-un mod care nu este transparent, interfeței (datele pot fi distribuite în diferite locații). În același timp, interfața cu utilizatorul alege ce informație să se afișeze și cum bazându-se pe detaliile de aspect (the look and feel) și pe specificații ale interfeței, nu bazat pe structura în care datele sunt stocate.
Integrarea comunicării între interfața grafică și server-ul de servicii prin Web Services utilizate pentru a accesa date sau pentru a efectua anumite operații necesare a contribuit la realizarea unui design decuplat împlinind astfel promisiunea oferită de un design bazat pe arhitectura SOA.
Deoarece interfața utilizator orientată pe servicii transmite și primește informații de la servicii utilizând mesaje simple SOAP (care sunt, de fapt, mesaje XML formatate conform standardului SOAP), serviciile pot fi scrise în orice limbaj. Cu alte cuvinte, interfața grafică orientată pe servicii este independentă de limbaj. Se poate schimba limbajul de programare al server-ului fără a cauza deloc schimbări la nivelul interfeței grafice.
La nivel de transport, comunicarea se realizează utilizând protocolul HTTP.
Astfel, prin lucrarea de față, s-a realizat suportul practic necesar pentru ca interfața grafică să poată comunica cu server-ul de servicii Web utilizând comunicație prin mesaje SOAP. Astfel s-a implementat practic pe partea de client modulul responsabil de asigurarea comunicării componentelor grafice ale interfeței cu serviciile web pentru a accesa datele (afișare locații și/sau conținut media disponibil) sau pentru a îndeplini anumite funcționalități (autentificare).
De asemenea, pe partea de server s-au implementat într-o manieră contract – first servicii necesare pentru a putea fi folosite de interfața grafică în vederea afișării datelor.
Adoptarea utilizării framework-ului de Spring pentru implementarea de servicii Web atât pe partea client cât și pe partea de server contribuie substanțial la ușurarea implementării și a integrării acestora în aplicație.
De asemenea, adoptarea soluției de a delega instanțierea obiectelor unui container ce utilizează principiul de IoC s-a reflectat în implementare asigurând un design decuplat, simplu și flexibil al ierarhiei de clase implicate în implementarea serviciilor Web atât pe partea de client, cât și pe partea de server. Obiectele au dependințe numai tipuri abstracte și acest fapt contribuie foarte mult și la facilitarea adăugării testelor unitare pe viitor.
Realizarea implementării a scos în evidență faptul că aplicarea conceptelor SOA la o aplicație grafică și delegarea responsabilității de gestionare a ciclului de viață unui container folosind container-ul de IoC de la Spring poate îmbunătăți considerabil eficiența unui dezvoltator de software .
Un ajutor deosebit ca performanță și ușurință în folosire a fost și alegerea utilizării framework-ului JiBX ca și soluție de realizare a conversiilor între obiectele Java și mesajele XML necesare la realizarea comunicării folosind servicii Web bazare pe mesaje SOAP între aplicația client și server-ul de servicii Web.
Prin comunicarea cu servicii Web s-a creat un contract bazat pe mesaje simple între interfață grafică bazată pe servicii și serviciile necesare. Rezultatul este o decuplare aproape completă a clientului de server, ele fiind legate numai prin contractul de mesaje de comunicare.
Se pot crea clienți proptotip care sunt funcționali complet pentru că se pot utiliza handler-i de mesaje locali falși. Interfața grafică orientată pe servicii nu cunoaște diferența dintre a folosi un serviciu propriu-zis și a utiliza handler-i de mesaje falși.
Așadar, în relizarea practică a lucrării s-au folosit tehnologii avansate care pot contribui substanțial la eficientizarea procesului de dezvoltare a unui astfel de software și care au permis realizarea concretă a aspectelor propuse referitoare la reutilizarea funcțiilor, a asigurării unei performanțe bune a sistemului, a ușurinței în comunicare și a interoperabilității între diversele componente ale aplicației.
In final se poate concluziona ca serviciile Web ofera un mediu distribuit in care aplicatii si componente de aplicatii diverse pot comunica intre ele cu usurinta intr-o maniera independenta de platforma si de limbajul de programare. Aceasta interoperabilitate aduce eterogenitate in lumea aplicatiilor distribuite.
Bibliografie
[1] TIMFOTE, Carmen. Web Services – o arhitectură orientată pe servicii, Revista Informatică Economică, nr. 4(28)/2003.
[2] Bevis, Tony. Java Design Pattern Essentials – Second Edition, Ability First Limited; 2nd edition edition, October 11, 2012
[3] Erl, Thomas. Service-Oriented Architecture, Concepts, Technology, and Design. s.l.: Prentice Hall Indiana, 2006, pp 33 – 34, 40 – 42.
[4] Myerson, Judith. Web Services Architectures, Tech, 2002
[5] Cerami, Ethan. Web Services Essentials (O'Reilly XML), February 21, 2002
[6] Papazoglou, Michael. Web Services: Principles and Technology. s.l : Prentic Hall, 2008.
[7] Erl, Thomas. Service-Oriented Architecture, Concepts, Technology, and Design. s.l. : Prentice Hall Indiana, 2006
[8] Seddighi , Ahmad Reza. Spring Persistence with Hibernate, Packt, 2009, pp 227 – 270
[9] Walls, Craig. Spring in Action, Third Edition, July 2, 2011
[10] Martin, Robert C. Clean Code: A Handbook of Agile Software Craftsmanship, Prentice Hall, August 11, 2009
[11] Charitha, Kankanamge . Web Services Testing with soapUI, Packt, 2012
[12] Rotem-Gal-Oz, Arnon. SOA Patterns, Manning, September 24, 2012.
[13] Kunjumohamed Shameer and Sattari Hamidreza . Spring Web Services 2 Cookbook, Packt, 2012
[14] Daigneau, Robert. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services, Addison-Wesley, November 4, 2011
[15] Horstmann Cay S. and Cornell Gary . Core Java Volume I–Fundamentals (9th Edition) (Core Series), Prentice Hall, 9 edition, December 7, 2012
[16] Horstmann Cay S. and Cornell Gary . Core Java Volume II–Advanced Features (9th Edition) (Core Series)
[17] Damith C. Rajapakse, A Fresh Graduate’s Guide to Software Development Tools and Technologies, 2012, Chapter 10, pp. 10 http://www.comp.nus.edu.sg/~seer/book/2e/Ch10. Service Oriented Architecture.pdf
[18] Point, Tutorials. What are Web serivces.
http://www.tutorialspoint.com/webservices/what_are_web_services.htm
[19] Servicii Web,
http://www.scritub.com/stiinta/informatica/Arhitectura-Orientata-Servicii84291.php
[20] SOAP http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devnet/webservicesprotocol_xml.html
[21] W3C. Web Service Description Language (WSDL)1.1.
http://www.w3.org/TR/wsdl
[22] Spring, The IoC container,
http://docs.spring.io/spring/docs/3.0.x/reference/beans.html
[23] Bean Definition,
http://www.tutorialspoint.com/spring/spring_bean_definition_inheritance.htm
[24] Service Arhitecture,
http://www.service-architecture.com/articles/web-ervices/web_services_explained.html
Anexe
Anexa 1 : Clasa SpringFactoryBean
package com.mcc.container.impl;
import org.springframework.beans.factory.FactoryBean;
import com.mcc.container.Factory;
/**
*/
class SpringFactoryBean implements FactoryBean {
private Factory factory;
private Class objectType;
private boolean singleton;
public Object getObject() throws Exception {
return factory.create();
}
public Class getObjectType() {
return objectType;
}
public boolean isSingleton() {
return singleton;
}
public void setFactory(Factory factory) {
this.factory = factory;
}
public void setObjectType(Class objectType) {
this.objectType = objectType;
}
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
}
Anexa 2 : Exemplu fisier de conversie Java/XML
<?xml version="1.0" encoding="UTF-8"?>
<binding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="binding.xsd">
<namespace uri="http://www.mcc.com/mcc/ws/schemas"
prefix="mcc" default="all" />
<mapping name="LoginRequest"
class="com.mcc.client.transport.clientws.LoginRequest">
<value name="username" field="username" />
<value name="password" field="password" />
</mapping>
<mapping name="LoginResponse"
class="com.mcc.client.transport.clientws.LoginResponse">
<structure name="User" field="user">
<value name="id" set-method="setId" get-method="getId" />
<value name="username" set-method="setUsername" get-method="getUsername" />
<value name="sessionid" set-method="setSessionId" get-method="getSessionId" />
</structure>
</mapping>
</binding>
Anexa 3 : Fisierul WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://www.mcc.com/">
<wsdl:types>
<xs:schema elementFormDefault="qualified"
targetNamespace="http://www.mcc.com/mcc/ws/schemas">
<xs:element name="GetMediaContentLocationsRequest">
<xs:complexType />
</xs:element>
<xs:element name="GetMediaContentLocationsResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="repositories">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0"
name="repository" type="tns:MediaContentRepository">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="MediaContentRepository">
<xs:sequence>
<xs:element name="id" type="xs:long" />
<xs:element name="name" type="xs:string" />
<xs:element name="locations">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0"
name="MediaLocation" type="tns:MediaLocation">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MediaLocation">
<xs:sequence>
<xs:element name="id" type="xs:long" />
<xs:element name="status" type="tns:MediaLocationStatus" />
<xs:element name="type" type="tns:MediaLocationType" />
<xs:element name="name" type="xs:string" />
<xs:element name="mediaObjectsCount" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="MediaLocationStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="OFFLINE" />
<xs:enumeration value="ONLINE" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MediaLocationType">
<xs:restriction base="xs:string">
<xs:enumeration value="CACHE" />
<xs:enumeration value="VIDEO_LIBRARY" />
<xs:enumeration value="MEDIA_SERVER" />
</xs:restriction>
</xs:simpleType>
<xs:element name="LoginRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="username" type="xs:string" />
<xs:element name="password" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="LoginResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="User" type="tns:User" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="id" type="xs:int" />
<xs:element name="username" type="xs:string" />
<xs:element name="sessionid" type="xs:string" />
</xs:sequence>
</xs:complexType>
…
</xs:schema>
</wsdl:types>
<wsdl:message name="LoginResponse">
<wsdl:part element="schema:LoginResponse" name="LoginResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetMediaContentLocationsRequest">
<wsdl:part element="schema:GetMediaContentLocationsRequest"
name="GetMediaContentLocationsRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetMediaContentLocationsResponse">
<wsdl:part element="schema:GetMediaContentLocationsResponse"
name="GetMediaContentLocationsResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="LoginRequest">
<wsdl:part element="schema:LoginRequest" name="LoginRequest">
</wsdl:part>
</wsdl:message>
…
<wsdl:portType name="MediaContentServer">
<wsdl:operation name="GetMediaContentLocations">
<wsdl:input message="tns:GetMediaContentLocationsRequest"
name="GetMediaContentLocationsRequest">
</wsdl:input>
<wsdl:output message="tns:GetMediaContentLocationsResponse"
name="GetMediaContentLocationsResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Login">
<wsdl:input message="tns:LoginRequest" name="LoginRequest">
</wsdl:input>
<wsdl:output message="tns:LoginResponse" name="LoginResponse">
</wsdl:output>
</wsdl:operation>
…
</wsdl:portType>
<wsdl:binding name="MediaContentServerBinding" type="tns:MediaContentServer>
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetMediaContentLocations">
<soap:operation soapAction="" />
<wsdl:input name="GetMediaContentLocationsRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="GetMediaContentLocationsResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Login">
<soap:operation soapAction="" />
<wsdl:input name="LoginRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="LoginResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
…
</wsdl:binding>
<wsdl:service name="MediaContentServerService">
<wsdl:port binding="tns:MediaContentServerBinding" name="MediaContentServerPort">
<soap:address location="http://localhost:8888/mcc-server/serverws" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Bibliografie
[1] TIMFOTE, Carmen. Web Services – o arhitectură orientată pe servicii, Revista Informatică Economică, nr. 4(28)/2003.
[2] Bevis, Tony. Java Design Pattern Essentials – Second Edition, Ability First Limited; 2nd edition edition, October 11, 2012
[3] Erl, Thomas. Service-Oriented Architecture, Concepts, Technology, and Design. s.l.: Prentice Hall Indiana, 2006, pp 33 – 34, 40 – 42.
[4] Myerson, Judith. Web Services Architectures, Tech, 2002
[5] Cerami, Ethan. Web Services Essentials (O'Reilly XML), February 21, 2002
[6] Papazoglou, Michael. Web Services: Principles and Technology. s.l : Prentic Hall, 2008.
[7] Erl, Thomas. Service-Oriented Architecture, Concepts, Technology, and Design. s.l. : Prentice Hall Indiana, 2006
[8] Seddighi , Ahmad Reza. Spring Persistence with Hibernate, Packt, 2009, pp 227 – 270
[9] Walls, Craig. Spring in Action, Third Edition, July 2, 2011
[10] Martin, Robert C. Clean Code: A Handbook of Agile Software Craftsmanship, Prentice Hall, August 11, 2009
[11] Charitha, Kankanamge . Web Services Testing with soapUI, Packt, 2012
[12] Rotem-Gal-Oz, Arnon. SOA Patterns, Manning, September 24, 2012.
[13] Kunjumohamed Shameer and Sattari Hamidreza . Spring Web Services 2 Cookbook, Packt, 2012
[14] Daigneau, Robert. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services, Addison-Wesley, November 4, 2011
[15] Horstmann Cay S. and Cornell Gary . Core Java Volume I–Fundamentals (9th Edition) (Core Series), Prentice Hall, 9 edition, December 7, 2012
[16] Horstmann Cay S. and Cornell Gary . Core Java Volume II–Advanced Features (9th Edition) (Core Series)
[17] Damith C. Rajapakse, A Fresh Graduate’s Guide to Software Development Tools and Technologies, 2012, Chapter 10, pp. 10 http://www.comp.nus.edu.sg/~seer/book/2e/Ch10. Service Oriented Architecture.pdf
[18] Point, Tutorials. What are Web serivces.
http://www.tutorialspoint.com/webservices/what_are_web_services.htm
[19] Servicii Web,
http://www.scritub.com/stiinta/informatica/Arhitectura-Orientata-Servicii84291.php
[20] SOAP http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devnet/webservicesprotocol_xml.html
[21] W3C. Web Service Description Language (WSDL)1.1.
http://www.w3.org/TR/wsdl
[22] Spring, The IoC container,
http://docs.spring.io/spring/docs/3.0.x/reference/beans.html
[23] Bean Definition,
http://www.tutorialspoint.com/spring/spring_bean_definition_inheritance.htm
[24] Service Arhitecture,
http://www.service-architecture.com/articles/web-ervices/web_services_explained.html
Anexe
Anexa 1 : Clasa SpringFactoryBean
package com.mcc.container.impl;
import org.springframework.beans.factory.FactoryBean;
import com.mcc.container.Factory;
/**
*/
class SpringFactoryBean implements FactoryBean {
private Factory factory;
private Class objectType;
private boolean singleton;
public Object getObject() throws Exception {
return factory.create();
}
public Class getObjectType() {
return objectType;
}
public boolean isSingleton() {
return singleton;
}
public void setFactory(Factory factory) {
this.factory = factory;
}
public void setObjectType(Class objectType) {
this.objectType = objectType;
}
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
}
Anexa 2 : Exemplu fisier de conversie Java/XML
<?xml version="1.0" encoding="UTF-8"?>
<binding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="binding.xsd">
<namespace uri="http://www.mcc.com/mcc/ws/schemas"
prefix="mcc" default="all" />
<mapping name="LoginRequest"
class="com.mcc.client.transport.clientws.LoginRequest">
<value name="username" field="username" />
<value name="password" field="password" />
</mapping>
<mapping name="LoginResponse"
class="com.mcc.client.transport.clientws.LoginResponse">
<structure name="User" field="user">
<value name="id" set-method="setId" get-method="getId" />
<value name="username" set-method="setUsername" get-method="getUsername" />
<value name="sessionid" set-method="setSessionId" get-method="getSessionId" />
</structure>
</mapping>
</binding>
Anexa 3 : Fisierul WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://www.mcc.com/">
<wsdl:types>
<xs:schema elementFormDefault="qualified"
targetNamespace="http://www.mcc.com/mcc/ws/schemas">
<xs:element name="GetMediaContentLocationsRequest">
<xs:complexType />
</xs:element>
<xs:element name="GetMediaContentLocationsResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="repositories">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0"
name="repository" type="tns:MediaContentRepository">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="MediaContentRepository">
<xs:sequence>
<xs:element name="id" type="xs:long" />
<xs:element name="name" type="xs:string" />
<xs:element name="locations">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0"
name="MediaLocation" type="tns:MediaLocation">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MediaLocation">
<xs:sequence>
<xs:element name="id" type="xs:long" />
<xs:element name="status" type="tns:MediaLocationStatus" />
<xs:element name="type" type="tns:MediaLocationType" />
<xs:element name="name" type="xs:string" />
<xs:element name="mediaObjectsCount" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="MediaLocationStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="OFFLINE" />
<xs:enumeration value="ONLINE" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MediaLocationType">
<xs:restriction base="xs:string">
<xs:enumeration value="CACHE" />
<xs:enumeration value="VIDEO_LIBRARY" />
<xs:enumeration value="MEDIA_SERVER" />
</xs:restriction>
</xs:simpleType>
<xs:element name="LoginRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="username" type="xs:string" />
<xs:element name="password" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="LoginResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="User" type="tns:User" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="id" type="xs:int" />
<xs:element name="username" type="xs:string" />
<xs:element name="sessionid" type="xs:string" />
</xs:sequence>
</xs:complexType>
…
</xs:schema>
</wsdl:types>
<wsdl:message name="LoginResponse">
<wsdl:part element="schema:LoginResponse" name="LoginResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetMediaContentLocationsRequest">
<wsdl:part element="schema:GetMediaContentLocationsRequest"
name="GetMediaContentLocationsRequest">
</wsdl:part>
</wsdl:message>
<wsdl:message name="GetMediaContentLocationsResponse">
<wsdl:part element="schema:GetMediaContentLocationsResponse"
name="GetMediaContentLocationsResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="LoginRequest">
<wsdl:part element="schema:LoginRequest" name="LoginRequest">
</wsdl:part>
</wsdl:message>
…
<wsdl:portType name="MediaContentServer">
<wsdl:operation name="GetMediaContentLocations">
<wsdl:input message="tns:GetMediaContentLocationsRequest"
name="GetMediaContentLocationsRequest">
</wsdl:input>
<wsdl:output message="tns:GetMediaContentLocationsResponse"
name="GetMediaContentLocationsResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Login">
<wsdl:input message="tns:LoginRequest" name="LoginRequest">
</wsdl:input>
<wsdl:output message="tns:LoginResponse" name="LoginResponse">
</wsdl:output>
</wsdl:operation>
…
</wsdl:portType>
<wsdl:binding name="MediaContentServerBinding" type="tns:MediaContentServer>
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetMediaContentLocations">
<soap:operation soapAction="" />
<wsdl:input name="GetMediaContentLocationsRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="GetMediaContentLocationsResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Login">
<soap:operation soapAction="" />
<wsdl:input name="LoginRequest">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="LoginResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
…
</wsdl:binding>
<wsdl:service name="MediaContentServerService">
<wsdl:port binding="tns:MediaContentServerBinding" name="MediaContentServerPort">
<soap:address location="http://localhost:8888/mcc-server/serverws" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Extinderea Interoperabilitatii Aplicatiilor Software (ID: 149803)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
