marți, 30 iunie 2009

Servicii web cu jax-ws: Partea 2

Acest post vine ca o continuare pentru prima parte despre serviciile web cu jax-ws. O problema care apare des in serviciile web este aceea a datelor ce pot fi returnate. Un exemplu posibil este urmatorul: Am un EJB care modeleaza o persoana. Cum pot sa il returnez? O abordare naiva ar putea fi aceea de a specifica return type-ul ca fiind clasa EJB-ului. De ce nu este corecta aceasta abodare? In momentul in care clientul primeste obiectul si incearca de exemplu sa acceseze un element dintr-o colectie de tip OneToMany nu va putea face acest lucru(session closed). Ce putem face? Putem scrie un obiect wrapper care sa fie serializabil. In metoda serviciului web construim obiectul wrapper pe baza ejb-ului incarcat. Avem grija sa nu folosim tipuri de colectii de genul List, Set, etc... Vom folosi in schimb vectori normali []. Codul de mai jos exemplifca acest lucru.

@Entity
public class Persoana {
@Id
private long cnp;

@OneToMany(mappedBy="parinte")
private List rude;


//metode getter/setter
}


public class PersoanaWrapper implements Serializable {
private long cnp;

private PersoanaWrapper[] rude;

//metode getter/setter
}


Metoda din webservice care doreste sa returneze o persoana ar putea fi implementat de maniera urmatoare:

public PersoanaWrapper getPersoana(long cnp) {
//cod prin care incarc ejb-ul persoanei dorite. => Persoana persEJB;
PersoanaWrapper pers = new PersoanaWrapper();
int nrRude = persEJB.getRude().size();

pers.setCNP(persEJB.getCNP());
pers.setRude(new PersoanaWrapper[nrRude]);

for(int i = 0; i < nrRude; i++) {
PersoanaWrapper tmp = new PersoanaWrapper();
tmp.setCNP(persEJB.getRude().get(i).getCNP());
pers.getRude()[i] = tmp;
}

return pers;
}

O imbunatatire vizibila a codului de mai sus este reprezentata de adaugarea unei metode/constructor de copiere: "valueOf". Utilizand clase wrapper, puteti sa returnati orice tip de date doriti.
S-a mentionat intr-un post anterior ca in momentul in care un serviciu web este deployat in container el va fi expus si ca Session bean. Este recomandat totusi sa accesati serviciul ori ca session bean ori ca web service(de preferat web service) pentru a fi sigur ca toate metodele sunt functionale.

Cum pot injecta resursa in serviciul web?

De cele mai multe ori este nevoie sa interactionam intr-un fel cu un sistem backend(o baza de date, un fisier txt, etc..) Pentru acest lucru, in Java EE exista PersistenceContext. Contextul de persistenta poate fi injectat usor utilizand urmatoarele linii de cod:

@PersistenContext(unitName="myPersistence")
private EntityManager em;

Contextul de persistenta nu este singura resursa care poate fi injectata intr-un serviciu web. Alte resurse pot fi de asemenea injectat. De exemplu un mail session sau un datasource(pentru bd). Presupun ca avem un DataSource mapat ca: java:jdbc/MyDS. Pentru a-l face disponibil in cod este suficient sa folosesc urmatoarea constructie:

@Resource(mappedName="java:jdbc/MyDS")
private DataSource ds;

Se procedeaza analog pentru orice fel de resursa doriti sa injectati. Intr-un post urmator voi arata cateva strategii pentru securizarea unui serviciu web.

Niciun comentariu:

Trimiteți un comentariu