En ce moment, au bureau, je bosse sur une appli web Java. Dans la foultitude des framework disponible, on a choisi d’utilisé Tapestry. Mon Java est un peu rouillé, et je débute (comme tout le monde chez nous) sur ce framework. En créant mon premier beanediform, je suis tombé sur un comportement surprenant au premier abord pour lequel je n’ai pas trouvé beaucoup d’info. Comme ça peut être utile, autant à d’autre qu’à moi même en pense bête, je raconte ça ici.
Imaginons donc une classe Login de base :
Jusque là, tout va bien. Imaginons maintenant une page qui ferait un formulaire pour saisir les informations de cette classe. Le .tml associé contiendrait <t:beaneditform object=login/>
. Et jusque là, ça va encore. En compilant, et testant la page, on devrait obtenir le résultat escompté.
Imaginons maintenant, que pour les besoins de l’application, par ailleurs, j’ai besoin d’un constructeur pour la classe Login. Pas de soucis, on lui rajoute :
Rien de plus simple. Sauf que… Sauf que quand vous allez réutiliser la page de formulaire, vous risquez d’avoir des trucs bizarres : les champs de votre formulaire sont peuplés avec des informations qui sortent d’on ne sait où, il se pourrait même que vous tombiez sur des erreurs types service not found. Pas très classe…
La solution (version courte) : il suffit de rajouter un constructeur sans arguments, et l’injecter en tant que service.
La solution (version longue)1 : C’est la même :)
Mais je m’explique un peu. Le problème vient que Tapestry est intelligent et essaie de faire des choses intelligentes2. En bref, si on ne définit pas de constructeur, Tapestry utilisera le constructeur vide sans argument que le compilateur aura eu la bonté de faire pour nous pour instancier un objet Login.
Si on rajoute un constructeur avec des arguments, Tapestry va essayer de s’en servir3, et comme il n’a, à ce moment, pas toutes les infos pour le faire, il va se passer des choses bizarres4. En définissant le constructeur vide et en utilisant l’annotation @inject, on va déclarer ce constructeur comme service à Tapestry. En gros, on va lui dire que c’est ce constructeur qu’il devra utiliser et pas l’autre. Ainsi pas de soucis.
-
mais dans les grandes lignes ↩
-
Et on sait bien qu’avec un code simple, être intelligent n’est pas forcément une bonne idée :) ↩
-
si j’ai bien compris, son comportement par défaut et d’utiliser le constructeur qui utilise le plus de champs ↩
-
en C, on aurait probablement eu le droit à un magnifique Segmentation Fault :) ↩
Poursuivre la discussion
Envie de réagir à l'article ? Il suffit de me laisser un message via la page de contact, sur mastodon @avernois@piaille.fr ou un billet chez vous.
Vous pouvez aussi proposer des modifications via le source de cet article sur gitlab.