SeamFramework.orgCommunity Documentation
Pour ceux qui p^réfère utiliser le Google Web Toolkit (GWT) pour développer des applications AJAX dynamique, Seam fourni une couche d'intégration qui permet aux widgets GWT d'interagir directement avecc les composants de Seam.
Pour utiliser GWT, nous allons postuler que vous êtes déjà familier avec les outils GWT - plus d'informations peut ête trouvée sur http://code.google.com/webtoolkit/. Ce chapitre n'essaye pas d'expliquer comment GWT fonctionne et comment l'utiliser.
Il n'y a pas de configuration spécialé nécéssaire pour utiliser GWT dans une application Seam, cependant le servlet de ressource de Seam doit être installé. Voir Chapitre 30, Configuring Seam and packaging Seam applications pour les détails.
La première étape dans la préparation du composant dfe Seam est d'être appelé via GWT, cela créer deux interfaces de service synchrone et assynchrone pour les méthode que vous souhaitez appeler. Ces deux interfaces devraient étendre l'interface GWT com.google.gwt.user.client.rpc.RemoteService
:
public interface MyService extends RemoteService {
public String askIt(String question);
}
L'interface asynchrone devrait être identique, à la différence qu'il doit contenir un paramètre additionnel AsyncCallback
pour chaque méthode qu'il déclare:
public interface MyServiceAsync extends RemoteService {
public void askIt(String question, AsyncCallback callback);
}
L'interface assynchrone, dans cet exemple MyServiceAsync
, sera implémenté par GWT et ne devrait pas être implémenté directement.
L'étape suivante, est de créer un composant de Seam qui implémente l'interface synchrone:
@Name("org.jboss.seam.example.remoting.gwt.client.MyService")
public class ServiceImpl implements MyService {
@WebRemote
public String askIt(String question) {
if (!validate(question)) {
throw new IllegalStateException("Hey, this shouldn't happen, I checked on the client, " +
"but its always good to double check.");
}
return "42. Its the real question that you seek now.";
}
public boolean validate(String q) {
ValidationUtility util = new ValidationUtility();
return util.isValid(q);
}
}
Le nom du composant seam doit correspondre au nom pleinement qualifié de l'interface client GWT (comme montré), ou ne servlet de ressource de seam ne sera pas capable de le trouver quand un client fait un appel GWT. Les méthodes qui sont accéssible via GWT doivent aussi être annotées avec l'annotation @WebRemote
.
La prochaine étape est d'écrire une méthode qui retourne un itnerface assynchrone vers le composant. Cette méthode est localisée dans la classe widget, et sera utilisé avec le widget pour obtenir une référence vers un squelette de client assynchrone:
private MyServiceAsync getService() {
String endpointURL = GWT.getModuleBaseURL() + "seam/resource/gwt";
MyServiceAsync svc = (MyServiceAsync) GWT.create(MyService.class);
((ServiceDefTarget) svc).setServiceEntryPoint(endpointURL);
return svc;
}
La dernière étape est d'écrire le code du widget qui invoque la méthode sur le squelette du client. L'exemple suivant créer un interface utilisateur simple avec un label, une zone de saisie et un bouton:
public class AskQuestionWidget extends Composite {
private AbsolutePanel panel = new AbsolutePanel();
public AskQuestionWidget() {
Label lbl = new Label("OK, what do you want to know?");
panel.add(lbl);
final TextBox box = new TextBox();
box.setText("What is the meaning of life?");
panel.add(box);
Button ok = new Button("Ask");
ok.addClickListener(new ClickListener() {
public void onClick(Widget w) {
ValidationUtility valid = new ValidationUtility();
if (!valid.isValid(box.getText())) {
Window.alert("A question has to end with a '?'");
} else {
askServer(box.getText());
}
}
});
panel.add(ok);
initWidget(panel);
}
private void askServer(String text) {
getService().askIt(text, new AsyncCallback() {
public void onFailure(Throwable t) {
Window.alert(t.getMessage());
}
public void onSuccess(Object data) {
Window.alert((String) data);
}
});
}
...
Quand on clique, le bouton appelle la méthode askServer()
en passant le contenu de la zone de saisie (dans cet exemple, la validation est aussi réalisé pour s'assurer que la zone de saiie contient une question valide). La méthode askServer()
obtient une référencer vers un squelette de client assynchrone (retournée par la méthode getService()
) et invoque la méthode askIt()
. Le résultat (ou le message d'erreursi l'appel échoue) est affiché dans une fenètre d'alerte.
Le code complet pour cet exemple peut être trouvé dans la distribution de Seam dans le dossier examples/remoting/gwt
.
Pour le déploiement des applications GWT, il ya une étape de compilation vers Javascript (avec compactage et cryptage du code). Il y a un utilitaire de ant qui peut être utilisé au lieu de la ligne de commande ou de l'utilitaire GUI que GWT fourni. Pour l'utiliser, vous allez avoir besoin d'avoit le jar de tâche ant dans votre classpath, tout comme le GWT téléchargé (avec ce que vous avez besoin pour votre mode hébergement).
Ensuite, dans votre fichier ant, mettez (presque en haut de votre fichier ant):
<taskdef uri="antlib:de.samaflost.gwttasks"
resource="de/samaflost/gwttasks/antlib.xml"
classpath="./lib/gwttasks.jar"/>
<property file="build.properties"/>
Créez un fichier build.properties
, qui va avoir ce contenu:
gwt.home=/gwt_home_dir
Ceci devrait bien sûr pointer vers le dossier où GWT doit être installé. Ensuite, utilisez le pour créer une cible:
<!-- the following are are handy utilities for doing GWT development.
To use GWT, you will of course need to download GWT seperately -->
<target name="gwt-compile">
<!-- in this case, we are "re homing" the gwt generated stuff, so in this case
we can only have one GWT module - we are doing this deliberately to keep the URL short -->
<delete>
<fileset dir="view"/>
</delete>
<gwt:compile outDir="build/gwt"
gwtHome="${gwt.home}"
classBase="${gwt.module.name}"
sourceclasspath="src"/>
<copy todir="view">
<fileset dir="build/gwt/${gwt.module.name}"/>
</copy>
</target
>
La cible quand appelée va compiler l'application GWT et la copier dans le dossier spécifiée (ce qui devrait être dans le coin webapp
de votre war - n'oubliez pas GWT génère des artefactes HTML et javascript). Vous n'éditez jamais le code résultant que gwt-compile
génère - vous devez toujours éditer le source dans le dossier GWT.
N'oubliez pas que GWT vient avec un mode navigable hébergé - vous devriez l'utiliser pendant que vous développez avec GWT. Si vous ne le faite pas, et compilez à chaque fois, vous n'allez pas avoir le meilleurs de ce kit de développement (dans les fait, si vous ne voulez ou ne pouvez utiliser le mode navigable hébergé, je vous déconseille FORTEMENT d'utiliser GWT - est ce bien clair!).