miercuri, 29 iulie 2009

JAX-WS Webservices: Part 2

This post continues previous one for offering new information about jax-ws webservices. One issue which is often met is related to return types of the web service. For instance: We implement an EJB component which models a person. How can I return this? I might try to specify for one of the webservice methods the EJB as a return type. This is so wrong. The EJB might have a collection resulting from a OneToMany relation. When the client will try to access an element of this collections an exception will be raised complaining about "session closed". To avoid this, we implement a new class(wrapper) which will be serializable. We make sure we don't use Java Collection types like Set, List, Hash, ..... We'll use arrays instead([]). In the web service method we populate all attributes of the wrapper class. The following example demonstrates this:

@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;
}

One enhancement of the example is to add a new method/constructor which accepts an argument with the EJB type. Using wrapper classes you cand return whatever custom data type you want.
I mentioned in a previous post that when deploying a java web service in a container it will be exposed as a web service and as a Session bean. I strongly encourage you to invoke it as a web service or as a Session bean(not both). If you intend to make your application interoperable then use just web services.

How can we inject resources in a web service?

It is common to use resources in a web service. For instance, we might need to use a DataSource from the container. We might want to inject an EntityManager in the webservice. Both situation are easily solved in Java EE:

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

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

We can use @Resource annotation to inject various resources like:
  • Mail session
  • Custom data sources
  • Other resources

Niciun comentariu:

Trimiteți un comentariu