Framework Ajax et Java – Partie 1/2

27 02 2006

Suite à mon premier article où je montrais une implémentation simple de l’objet XmlHttpRequest sous Struts, il serait dommage de considérer cette méthode comme idéale. Il existe en effet de nombreuses bibliothèques prêtes à l’emploi qui permettent d’accélerer le développement d’interfaces riches en AJAX.

Je vais tenter ici de comparer plusieurs de ces frameworks parmi les plus connus en me limitant à ceux open-source. La finalité de cet article n’est pas d’être le N-ième article publié à décrire les avantages de AJAX mais de regarder avec une vision pragmatique comment ils s’implémentent. Attention, ce guide n’est absolument pas exhaustif et ne cite que des frameworks dont j’ai déjà entendu parler.

N’étant pas un designer très balaise, je vais passer rapidement sur les framework avec des fonctionnalités quasi-uniquement cotés client.

Parmi ceux ci, on a :

Scriptaculous est bien connu par ceux qui codent avec ruby on rails car ce framework est directement intégré dans rails. Son utilisation est donc transparente dans ce langage et permet d’écrire du code comme :

<%= text_field_with_auto_complete :contact, :name %>

Et hop un champ texte avec auto-complétion… Par contre, si on veut utiliser scriptaculous avec un serveur Java, il faudra coder toute la partie serveur à la main, ce qui est beaucoup moins simple.

Le suivant est Rico basé lui-même sur Prototype (même librairie de base que scriptaculous). Comparé à scriptaculous, il semble plus complet avec des animations, gestion de Behavior, etc. Je ne suis pas spécialiste du sujet, si un lecteur le sent, qu’il n’hésite pas à me préciser les différences en commentaire et je les ajouterai au texte.

Dojo est un framework « lourd » qui tente de rassembler tout ce qu’on pourrait demander à un toolkit de browser. La liste des sous-projets est à ce titre impressionnante puisque le répertoire src contient 388 fichiers et 33 dossiers.

Plusieurs packages ou « editions » sont disponibles, mais la version qui nous intéresse est le package « Ajax-Edition ».

Avantages de dojo sur les autres : Gestion du bouton Back du navigateur. Ceci est un gros problème d’utilisabilité qui concerne tous les framework et Dojo propose une solution élégante :

Chaque appel XmlHttpRequest ressemble à ça :

dojo.io.bind({    url: "http://foo.bar.com/sampleData.js",    load: function(type, evaldObj){        // hide the form when we hear back that it submitted successfully        sampleFormNode.style.display = "none";    },    formNode: sampleFormNode });

Et bien, dans le cas où on veut gérer le retour arrière par bouton, un simple paramètre supplémentaire suffit :

dojo.io.bind({    ...    backButton: function(){        // ...and then when the user hits "back", re-show the form        sampleFormNode.style.display = "";   ... });

Pas mal non ! On peut même gérer si l’utilisateur appuie sur la flèche avant (Qui sera compté comme une action différente) avec un « :forward »

C’est une intention louable de traiter le problème du back mais son implémentation implique de rajouter 2 méthodes à chaque appel pour traiter les 2 cas, ce qui peut paraître un peu lourd à l’utilisation.

Dojo gère également le bookmarking. Il suffit de rajouter un parametre à la méthode de binding qui ajoutera une ancre fantôme de la forme #xxx à la fin de l’url. Une idée excellente et simple à mettre en oeuvre !

pour les framework spécial Java, à suivre avec la deuxième partie.



JSF ou AJAX ?

6 02 2006

Vous vous souvenez de JSF, les Java Server Faces qui allaient remplacer à coup sûr Struts et les JSP ? Je ne sais pas vous, mais JSF ca doit faire 6 mois que j’en entend quasiment plus parler.

Alors pour vérifier que je ne suis pas le seul, j’ai mesuré sur technorati la popularité de quelques termes :



7000 posts c’est pas mal 🙂



On peut en conclure que Struts est au moins 3 fois plus important avec 22 000 articles…

Le grand gagnant, mais tellement prévisible :



100 000 articles. Aucun commentaire, le buzz tourne à plein régime, il y a juste à attendre que la bulle se dégonfle 😉 .

P.S. : Même JSP renvoit 37 000 articles.

Conclusion : Pauvre JSF, on te souhaite un rapide retour sur le devant de la scène… (Pour voter pour JSF, taper « 1 » ).

Update:

Merci pour les commentaires constructifs postés.

Concernant le débat de savoir si JSF est une technologie d’avenir, je serais plutôt de l’avis d’alexis, c’est à dire en attente de voir un jour JSF réellement utilisé.

Car après avoir gouté au joies d’un environnement ASP.NET – Visual Studio avec composants riches, on se plait à rêver d’un jour où l’on disposera de la même toolbox sous Java (ce que JSF peut apporter).

En revanche le but de mon post était seulement de montrer où en était la buzz-machine actuelle sur certains mots-clés. Et là clairement, les bloggeurs ont plus envie de raconter comment ils ont réussi à implémenter pour la Nème fois un Input auto-complété que raconter leurs implémentations JSF…



Je programme en Control-Shift-F

27 01 2006

J’ai pris conscience que quand je codais sous Eclipse, j’étais un Control-Shift-F addict. Ce n’est encore déclaré comme maladie grave et c’est même carrément pratique !

Pour les non-initiés, le Control-Shift-F c’est le raccourci qui reformate entièrement la page en fonction de règles décrites dans les propriétés d’Eclipse.

L’intérêt de cette pratique est facile à comprendre puisqu’elle permet de respecter les normes Java (qui sont celles mises dans Eclipse) et de partager ces règles avec les autres développeurs. Donc ca c’est dit et ca parait évident.

Par contre, là où pour moi ca devient plus intéressant, c’est qu’à force de lire du code Java sous Eclipse, je me suis habitué à retrouver ce formalisme. Résultat, quand je tombe sur une classe non formatée, il me faut plus de temps pour déchiffrer (-défricher ?-) le contenu…

Mon utilisation de la fonction est même encore plus poussée, puisque quand j’effectue une modification dans le code (ajout d’une ligne, d’un commentaire, n’importe quoi d’autre), je vais systématiquement reformater le code. Le gros avantage c’est que je ne me prend jamais la tête sur les espacements et visuellement ça continue à être correct pour mes yeux habitués 😉 .

Bon formatage !



AJAX et Struts par l’exemple

6 01 2006

Premier vrai et long article technique de ce blog…

Préambule

On trouve aujourd’hui beaucoup de références sur le net sur AJAX ( XmlHTTPRequest en réalité ) mais peu d’éléments sur l’intégration de AJAX sur le framework Struts. Concernant les ressources francaises sur le sujet, c’est quasi inexistant en recherche sur Google. Je me suis donc décidé à écrire ce petit article technique. Attention, cet article n’explique pas réellement le fonctionnement de la technologie AJAX mais plutôt de son intégration avec le framework Struts.

Concept

Pour rappeler très briévement la technologie AJAX, il s’agit de permettre au navigateur d’effectuer des requêtes HTTP sur le serveur en Javascript et de mettre à jour dynamiquement le contenu de la page (via DHTML) sans recharger toute la fenêtre.

Rappel des étapes :

  1. Création d’un objet XmlHttpRequest (sous Javascript)
  2. Paramétrage de cet objet (url et méthode de callback)
  3. Exécution de la requête
  4. Coté serveur, on reçoit la requête que l’on traite puis on renvoie le résultat
  5. Le retour est traité dans la méthode callback préalablement définie

Pour plus d’informations, il existe de nombreux sites en parlant mieux que moi

Intégration avec Struts

Comme on peut le voir dans les étapes ci-dessus, l’intégration avec Struts ne se situe que lors de l’étape 4 puisque c’est la seule étape qui fait intervenir le serveur. Afin d’implémenter la réception des appels AJAX sur le serveur, plusieurs solutions sont possibles :

  • Ecrire des servlets spécifiques
  • Utiliser un framework comme DWR
  • Ecrire des actions Struts « standard » dédiés

La 1ère solution étant à proscrire et la deuxième impliquant l’utilisation d’un framework tiers, la solution d’actions dédiées est parfaitement adaptée pour des petites extensions sur des projets existants comme cela est souvent le cas avec l’utilisation de AJAX.

Mon exemple sera l’implémentation d’une page donnant l’heure du serveur. C’est un exemple trivial mais il permet de mettre en place la chaîne complète, ce qui est l’intérêt de cet article.

Etape 1 : Ecriture de la page HTML

On commence par la page HTML :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Test AJAX et Struts</title>
<script type="text/javascript">
<!- -  Ici on placera le code Javascript -->
</script>
</head>
<body>
<div id="form">
<form action="#">
<input type="button" name="Envoyer" onclick="appelAjaxExemple();" value="Je veux l'heure du serveur" />
 </form>
</div>
<hr />
<div id="resultat"> </div>
</body>
</html>

La page est la plus simple possible avec un simple bouton qui appelle la méthode Javascript et un DIV de résultat.
Ensuite on écrit le Javascript suivant entre les balises head :

// appelé dans la page function appelAjaxExemple() 
{ 	
ajaxCallRemotePage('ajaxAction.do'); 
}

Cette méthode est celle appelée par le bouton du formulaire. Il se contente d’appeler la méthode de traitement avec en paramètre l’action Struts qui traitera l’appel Asynchrone (voir plus bas)

 // Methode d'appel a une page en XmlHttpRequest 
function ajaxCallRemotePage(url) 
{     
if (window.XMLHttpRequest) 
{ 
// Non-IE browsers       	
req = new XMLHttpRequest();        	
req.onreadystatechange = processStateChange;         
req.open("GET", url, true);         
req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); 		
req.send(null); 	
} 	
else if (window.ActiveXObject) 
{ 
// IE       	
req = new ActiveXObject("Microsoft.XMLHTTP");        	
req.onreadystatechange = processStateChange;        	
req.open("GET", url, true);        	
req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); 		
req.send(); 	
} 	
else { 		
return; // Navigateur non compatible 	
}  
}

Il s’agit de l’implémentation technique de la couche XmlHTTPRequest, on peut voir que le code est écrit pour gérer les navigateurs IE et les autres (dont Firefox). La requête sur le serveur est effectuée au moment du send(). On peut voir aussi que la méthode de callback processStateChange est défini. C’est la méthode qui est appelée lorsque l’état de la requête bouge. Voici son code :

 // Methode private qui traite le retour de l'appel de "ajaxCallRemotePage" 
function processStateChange() 
{     
if (req.readyState == 4) 
{ // Complete       
if (req.status == 200) 
{ // OK response        
  // Pour le debug        
  alert("ok:"+req.responseText);    
   } else {         
     // Pour le debug          
     alert("Problem: " + req.statusText);     
     alert("status: " + req.status);   
   }  
} }

L’algorithme est relativement simple. Si l’état de la requête est à 4 (terminée), on vérifie que le serveur nous a renvoyé un code HTTP de 200 qui correspond à un OK serveur. Alors dans ce cas, on affiche le résultat retourné par le serveur sinon on affiche l’erreur…

Etape 2 : configuration de Struts

Je considère dans ce chapitre que Struts est déjà correctement installé. Si vous avez besoin d’un projet vide, vous pouvez utiliser le Struts-Blank.

On commence par déclarer dans le fichier struts-config, une nouvelle action correspondant à notre appel depuis le javascript :

  <action-mappings>    	
<!- - Declaration de notre action Struts -->        
<action            path="/ajaxAction"            type="com.jc.AjaxAction" />    
</action-mappings>

Le contenu de l’action mapping est relativement simple puisque on se contente d’appeler une classe Java qui effectuera le traitement serveur. On peut remarquer qu’il n’est pas nécéssaire de préciser une page jsp de résultat puisque c’est le code java qui écrit dans l’objet response.

Etape 3 : Ecriture de l’action Struts

Le code de l’action Struts est le suivant :

package com.jc; import java.io.PrintWriter; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.apache.struts.action.Action; 
import org.apache.struts.action.ActionForm; 
import org.apache.struts.action.ActionForward; 
import org.apache.struts.action.ActionMapping; 

public class AjaxAction extends Action { 	
 public ActionForward execute(ActionMapping mapping, ActionForm form,        HttpServletRequest request, HttpServletResponse response) throws Exception 
 {
  String valeur = "test"; 	    
  // Write the text to response 	   
  response.setContentType("text/html"); 	   
  PrintWriter out = response.getWriter(); 	   
  out.println(valeur); 	  
  out.flush(); 	   
  return null; 	
 } 
}

Le code est relativement simple, dans le sens où il se contente d’écrire dans le flux de sortie de la requête HTTP. On peut remarquer que le return est null, car on ne suit pas la logique des mappings Struts et que le Javascript lira directement le flux provenant du serveur.

Etape 4 : Le test

En ouvrant le navigateur sur la page de test on tombe sur cet écran :

Après un clic sur le bouton, la popup d’alert s’affiche avec le résultat retourné par le serveur :

Parfait, maintenant on implémente un peu de fonctionnel…

Etape 5 : Implémentation de l’affichage de l’heure du serveur

Maintenant que l’aller retour serveur fonctionne, on peut ajouter un peu de code applicatif pour montrer l’intérêt de ce framework. Dans notre exemple, au clic sur le bouton, le serveur va retourner son heure système qui sera affiché sur la page.

La première modification concerne le code de l’action Java :

A la place de :

String valeur = "test";

Récupérons plutôt l’heure système (attention aux imports) :

Date date = GregorianCalendar.getInstance().getTime(); 
String valeur = SimpleDateFormat.getDateTimeInstance().format(date);

Il ne reste plus qu’à modifier le javascript de la page : Dans le traitement du résultat :

if (req.status == 200) 
{ // OK response       
// Pour le debug       
alert("ok:"+req.responseText);

On remplace l’alert par :

  // alert("ok:"+req.responseText);       
  var d = document.getElementById('resultat');       
  d.innerHTML = req.responseText;

résultat sur la page :

conclusion

Cette petite introduction sera j’espère pratique pour les personnes souhaitant d’intégrer rapidement des requêtes asynchrones sur des applications déjà existantes. Mais pour une intégration plus poussée, l’utilisation de frameworks dédiés sera un gros plus.

Source du projet développé sous WTP 1.0 : AjaxProject.zip

bugs possibles

  • Attention à l’url de destination passé à la méthode Javascript dans un environnement Struts. Une solution est de récupérer dans le Javascript la base de l’application avec un code comme celui-ci :
var path = window.location.pathname; path = path.substring( 0, path.length - "actionCourante.do".length );
  • J’ai remarqué également un autre problème très génant avec le cache d’IE5/IE6 sous Windows 2000 (qui bizarrement fonctionnait sous IE6 – Windows XP). En fait, le navigateur mettait en cache les appels depuis XmlHTTPRequest : Résultat, plus rien ne se passait si on appelait 2x la même URL. Pour corriger ce problème, j’ai ajouté dans les paramètres d’appel :
req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");

Références intéressantes



Quel est le langage de programmation le plus utilisé ?

29 09 2005

Pris d’une étude datant de septembre 2005. Le gagnant est …

Lire la suite »



Raccourcis clavier, l’ami de l’homme

7 09 2005

Une chose que je peux vraiment conseiller à tout développeur est de connaître quelques raccourcis claviers.
Etant donné que j’utilise Eclipse comme IDE, voici les raccourcis que je trouve les plus pratiques :

  • Control-Shift-T :
    Permet de taper le nom d’une classe Java à ouvrir. Le plus de cette fonction est qu’elle recherche en dynamique à la saisie, qu’elle permet les * et qu’elle autorise l’abbrévation ! Par exemple, si je cherche la classe MonTypeDeDonnees alors je peux saisir « MTDD« .

    Capture d'Eclipse 3.1

  • Control-Shift-R :
    La même chose que précédemment mais sur les ressources, comme par exemple les fichiers jsp…

  • F3 :
    Permet de « plonger » dans la définition d’un objet Java. Très pratique pour naviguer entre les classes.

Je vais rester à ce niveau synthétique en espérant vous avoir mis l’eau à la bouche.

Concernant mes lecteurs potentiels qui n’utiliseraient pas Eclipse tous les jours -les pauvres-, le même conseil s’applique sous Visual Studio .NET :

  • SHIFT+F7 pour passez d’une page ASPX au codebehind, F7 pour le chemin inverse.
  • CTRL+PgUp/CTRL+PgDn : pour passer de la vue design à la vue html sur une page ASPX.

Et pour les derniers qui ne seraient même pas développeurs -là c’est sans espoir- : Sous Word, Control-S pour sauvegarder (mais qui ne connait pas!), Control-Shift-C et Control-Shift-V pour copier-coller le style sélectionné (Très utile).

Comme ça jai mis l’eau à la bouche de tout le monde et plus personne n’a soif !