Viadeo

Antoine Sabot-Durand

Pages

J'ecoute les Cast Codeurs

Qui est @In ? Qui est @Out ? Eclairsissement sur la bijection dans Seam (1ère partie)

 english 

Suite à la lecture de l’article de Chiral Software sur les annotations Seam @Factory et @Unwrap, j’ai pensé qu’il serait bon d’apporter quelques précisions sur le fontionnement de la bijection dans Seam à la lumière de mon expérience sur le sujet.

L’une des erreurs les plus répandues lorsque l’on utilise Seam est d’être trop confiant dans sa « magie ».
L’un des premiers pièges dans lequel vous pouvez tomber en commençant avec Seam concerne la surjection (traduction libre du concept d’outjecting).

Prenez ce code par exemple :

@Name("registerHdl") @Scope(ScopeType.CONVERSATION) public class RegisterHandler implements Serializable{ @Out private Registrant registrant=new Registrant(); @Create public void create() { } } ... @Entity public class Registrant { private Long id; private String firstName; private String lastName; private String email; private String origine; (getters and setters skiped) }

On définit un composant dans le scope conversation avec un champ privé contenant une entité surjectée avec le nom « registrant ».

Plus tard on voudra exploiter cette variable dans une vue :

pages.xml : ... <page view-id="/register.xhtml"> <begin-conversation join="true" /> <navigation> <rule if-outcome="ok"> <end-conversation /> <redirect view-id="/thanks.xhtml"></redirect> </rule> </navigation> </page> ...

register.xhtml : ... <span class="inputLabel">Your name : </span><br/> <h:inputText id="Name" styleClass="inputShort" required="true" value="#{registrant.lastName}"/> ...

Mais ça ne marche pas (une exception se déclenche lors de la soumission du formulaire). On a pourtant démarré une conversation dans le fichier pages.xml et fait appel à notre « registrant » surjecté dans le composant « registerHdl ».
Alors qu’est-ce qui cloche ?
Le problème vient du fait que le composant registerHdl n’est jamais créé et que le fait de solliciter la variable de contexte surjecté « registrant » n’entraîne pas la création du composant.
Pour déclencher cette création, on doit solliciter une méthode du composant. On pourrait mapper nos champ avec #{registerHdl.registrant} dans la vue après avoir défini des getter et setter sur registrant par exemple. Mais il y a mieux.
C’est ici que l’annotation @Factory entre en scène.

@Name("registerHdl") @Scope(ScopeType.CONVERSATION) public class RegisterHandler implements Serializable{ private Registrant registrant=new Registrant(); @Factory public Registrant getRegistrant() { return registrant; } public void setRegistrant(Registrant registrant) { this.registrant = registrant; } @Create public void create() { } }

Nous avons supprimé l’annotation @Out et avons ajouté un getter avec l’annotation @Factory. Cette nouvelle configuration déclenche la création du composant registerHdl lorsque l’on utilise #{registrant…} dans une vue.

En résumé @Out surjecte un champ comme variable de contexte après la création du composant, alors que @Factory déclenche si nécessaire la création du composant pour sujecter la valeur retournée par une méthode de ce dernier. @Out n’est visible que dans le cycle de vie du composant alors que @Factory est visible dans toute l’application.
Mais ce n’est pas la seule différence entre @Factory et @Out comme nous le verrons dans la deuxième partie de cet article

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Netvibes
  • Twitter
blog comments powered by Disqus