I. Introduction▲
Dans le monde du développement Java/Web, le paradigme a longtemps été
à l'utilisation de Java d'un bout à l'autre de la chaîne avec notamment,
pour la couche de présentation, l'utilisation des classiques Jsp/Struts, ou JSF et
des applications multipages.
Depuis quelque temps cependant réapparaît la mode des clients riches avec des applications
monopages (type Gmail). Cette place est maintenant occupée par de nombreux frameworks
JavaScript (JQueryUI, Sencha ExtJS, PrimeUI, etc.). Néanmoins, il existe au moins deux
frameworks Java offrant des capacités similaires : GWT et RAP qui fait l'objet de
cette présentation.
Le but de cet article est donc de faire une présentation succincte de la technologie et de sa mise
en œuvre. RAP (Remote Application Platform) est donc un framework permettant le
développement d'interfaces riches codées en Java pour de multiples clients
cibles :
- client lourd ;
- mobile ;
- cross-browser.
Il s'appuie notamment pour cela sur RWT (RAP Widget Toolkit), une implémentation de SWT qui utilise Qooxdoo pour la gestion du JavaScript. Il est également possible d'utiliser des widgets JFace. L'avantage de l'implémentation d'un toolkit préexistant est de proposer (si l'on n'utilise pas les widgets spécifiques) le single sourcing. C'est-à-dire le fait de pouvoir proposer une interface client lourd ou client Web en changeant juste l'implémentation de SWT à utiliser. Le schéma ci-dessous nous laisse voir la possibilité d'utiliser JFace et RWT. On y voit également apparaître un servlet container. Il est en effet possible de déployer une application RAP sur n'importe quel serveur d'applications.
II. Premiers pas▲
Le développement d'application RAP nécessite l'utilisation d'Eclipse packagé avec un set de plugins (Eclipse for RCP and RAP Developers). Le démarrage est rapide et bien expliqué via la documentation développeur (ici : http://eclipse.org/rap/developers-guide/). Il permet via l'utilisation de template, de définir une application coquille d'œuf dont le look ressemble fortement à celui d'Eclipse.
L'utilisation du template permet une prise en main rapide du code Java ainsi que des fichiers de configuration nécessaires au développement d'une application sans être obligé de posséder les connaissances nécessaires à une mise en place « from scratch ».
III. Développement basique▲
III-A. Design d'une vue▲
Dans cet exemple, nous allons donc ajouter une vue permettant d'afficher un formulaire de filtres et la liste résultante. Pour ce faire nous utilisons le wizard suivant :
La classe Java est générée avec son code d'initialisation basique. La vue a également été automatiquement ajoutée au descripteur de l'application. Il s'agit du fichier plugin.xml classiquement utilisé pour décrire les points d'extension des plugins Eclipse. Elle est automatiquement ouverte avec le WindowBuilder éditeur d'Eclipse qui offre trois onglets :
- l'onglet source permet d'afficher l'éditeur Java classique ;
- l'onglet binding permet d'attacher des variables de la classe aux widgets de la vue ;
- l'onglet design permet d'afficher un éditeur WYSIWYG (What You See Is What You Get) pour concevoir l'interface graphique.
L'onglet affiche une zone d'édition (ici la zone grise), une palette de widgets, une vue structure qui affiche la hiérarchie des composants de la page et la vue « Properties » permet d'éditer les paramètres des widgets.
Quelques clics de souris et quelques paramétrages nous permettent d'obtenir le résultat suivant en moins de cinq minutes :
III-B. Rendre la vue accessible▲
Nous ajoutons une nouvelle action à l'application générée :
package
com.sqli.mailui;
import
org.eclipse.jface.action.Action;
import
org.eclipse.jface.dialogs.MessageDialog;
import
org.eclipse.ui.IWorkbenchPage;
import
org.eclipse.ui.IWorkbenchWindow;
import
org.eclipse.ui.PartInitException;
/**
* When run, this action will open another instance of a view.
*/
public
class
OpenListAction extends
Action {
private
final
IWorkbenchWindow window;
private
int
instanceNum =
0
;
private
final
String viewId;
public
OpenListAction
(
IWorkbenchWindow window, String label, String viewId) {
this
.window =
window;
this
.viewId =
viewId;
setText
(
label);
// The id is used to refer to the action in a menu or toolbar
setId
(
ICommandIds.CMD_OPEN_LIST);
// Associate the action with a pre-defined command, to allow key bindings.
setActionDefinitionId
(
ICommandIds.CMD_OPEN_LIST);
setText
(
"List"
);
}
public
void
run
(
) {
if
(
window !=
null
) {
try
{
window.getActivePage
(
).showView
(
viewId, Integer.toString
(
instanceNum++
), IWorkbenchPage.VIEW_ACTIVATE);
}
catch
(
PartInitException e) {
MessageDialog.openError
(
window.getShell
(
), "Error"
, "Error opening view:"
+
e.getMessage
(
));
}
}
}
}
Et on ajoute l'action nouvellement définie à la classe ApplicationActionBarAdvisor et voici le rendu de la page conçue :
III-C. Rendre la vue accessible▲
On ajoute maintenant un listener sur le bouton « search » :
Et le code associé au listener :
btnSearch.addSelectionListener
(
new
SelectionAdapter
(
) {
@Override
public
void
widgetSelected
(
SelectionEvent e) {
fillUp
(
table);
}
}
);
// ...
// ...
// ...
protected
void
fillUp
(
Table table) {
String[][] items =
new
String[][]{{
"Einstein"
,"Fix Newton laws."
,"They doesn't work if you gain speed too much.
Don't forget to make cool sentences"},
{
"John Doe"
,"Find my name."
,"Damn memory"
}
,
{
"Jérôme"
,"Fix tap"
,"Too night, not tomorow"
}
,
{
"Armstrong"
,"Walk on moon"
,"And find a smart thing to say"
}
,
{
"Jérôme"
,"Fill up cra"
,"Why not as legendary as others?"
}}
;
table.removeAll
(
);
for
(
String[] values : items ){
TableItem item =
new
TableItem
(
table, SWT.NONE);
item.setText
(
0
,values[0
]);
item.setText
(
1
,values[1
]);
item.setText
(
2
,values[2
]);
}
}
Ci-dessous, la page après un clic sur le bouton « search » :
III-D. Le remoting▲
Cet exemple est intéressant, car il permet d'entrevoir une notion très avantageuse du Framework RAP. En effet, tous les widgets ont une double vie, chaque widget possède une instance sur le client, et une instance sur le serveur. La synchronisation des deux instances se fait de façon transparente pour le développeur grâce à du JSON et des requêtes AJAX. Dans notre cas, le listener sur le bouton exécute bien du code qui se trouve sur le serveur. L'intérêt de ce système est la prise en charge totale du remoting par le framework, mais ceci a un coût. En effet la synchronisation des widgets déclenche de très nombreux appels client/serveur, et se révèle donc plus coûteuse de ce point de vue que GWT qui lui, utilise un remoting explicite.
IV. Conclusion▲
On aperçoit vite le premier intérêt de cet outil, c'est-à-dire
la facilité de réalisation de prototype/maquette d'interface complexe. La
mise en place et le design graphique sont effectivement très simples. Quant au
remoting, il est caché au développeur et pris en charge par le framework, ce
qui permet de mettre en place très rapidement une maquette avec des données
et du mocking des composants business.
La facilité ainsi que l'outillage existant autour de RAP sont directement liés à son
origine - SWT/OSGi - ce qui se révèle être un avantage si l'on a un
développeur RCP dans son équipe. Sinon l'apprentissage et l'intégration de cet
écosystème peuvent se révéler longs et coûteux.
L'intégration avec Spring reste à ce jour le point noir du projet. Ainsi même s'il est
possible d'intégrer programmatiquement celui-ci, le travail reste répétitif. Il
est dommage de ne pas voir une intégration plus poussée comme cela se fait pour de
nombreux autres frameworks (et GWT tout particulièrement).
RAP reste donc un projet à suivre, en espérant voir émerger une meilleure
intégration avec des outils comme Spring ou CDI à l'avenir ce qui simplifierait la
courbe d'apprentissage lié à l'utilisation ce framework.
V. Remerciements▲
Cet article a été publié avec l'aimable autorisation de SQLI, le partenaire de référence des entreprises dans la définition, la mise en œuvre et le pilotage de leur transformation digitale. Nous tenons à remercier Claude Leloup pour la relecture orthographique et Alain BERNARD pour la mise au gabarit.