Dwr-java-ajax-application-sample-chap
Manuel d'initiation aux principaux savoir-faire d'ajax [Eng]
...
Interface utilisateur: Basic
Éléments
Dans ce chapitre, nous aborderons le travail concret. Nous développerons des exemples basés sur le DWR, qui montrent comment modifier dynamiquement les éléments communs de l'interface utilisateur, tels que les tables et les listes, ainsi que la complétion du champ. Nous réalisons également un squelette d'interface utilisateur dynamique pour nos échantillons qui contiendront tous les échantillons de ce livre.
La section sur les interfaces utilisateur dynamiques montre comment démarrer avec une application DWR et présente un squelette d'interface utilisateur qui servira à contenir les exemples de tables et de listes, ainsi que l'exemple de complétion de champ (autosuggest / autocomplete). Les exemples du chapitre suivant utiliseront le même squelette d'interface utilisateur, à l'exception des exemples d'applications du chapitre 7.
Voici les sections de ce chapitre:
La création d'une interface utilisateur dynamique commence avec la création d'un projet Web et une base pour les exemples mentionnés dans ce chapitre
 € ¢ Mettre en œuvre des tables et des listes ¨ â € "nous montre comment utiliser DWR avec eux
 € ¢ Mise en œuvre de l'achèvement du champâ € ™ a un échantillon pour l'achèvement du champ typique
Création d'une interface utilisateur dynamique
L'idée derrière une interface utilisateur dynamique est d'avoir un "cadre" commun pour tous les échantillons. Nous allons créer une nouvelle application Web, puis ajouter de nouvelles fonctionnalités à l'application au fur et à mesure. L'interface utilisateur ressemblera à la figure suivante:
...
L'interface utilisateur comporte trois zones principales: le titre / le logo qui est statique, les onglets dynamiques et la zone de contenu qui indique le contenu réel.
L'idée derrière cette implémentation est d'utiliser la fonctionnalité DWR pour générer des onglets et obtenir du contenu pour les pages à onglet. L'interface utilisateur à onglets est créée à l'aide d'un modèle CSS de la bibliothèque CSS Dynamic Drive (http://dynamicdrive.com/ style / csslibrary / item / css-tabs-menu). Les onglets sont lus à partir d'un fichier de propriétés, donc
il est possible d'ajouter dynamiquement de nouveaux onglets à la page Web. La capture d'écran suivante montre l'interface utilisateur.
Le diagramme de séquence suivant montre le flux d'application à partir de la perspective logique. En raison des fonctionnalités DWR intégrées, nous n'avons pas besoin de nous inquiéter du fonctionnement de "truc" AJAX asynchrone. C'est, bien sûr, une bonne chose.
Nous allons maintenant développer l'application en utilisant l'Eclipse IDE et l'environnement de test Geronimo que nous avons mis en place dans le chapitre précédent.
Créer un nouveau projet Web
- Nous allons d'abord créer un nouveau projet web. À l'aide de l'IDE Eclipse, nous procédons comme suit: sélectionnez le menu Fichier | Nouveau | Projet Web dynamique.
- Cela ouvre la boîte de dialogue Nouveau projet Web dynamique. entrez le nom du projet DWREasyAjax et cliquez sur Suivant, et acceptez les valeurs par défaut sur toutes les pages jusqu'à la dernière page, où Geronimo Deployment Plan est créé comme indiqué dans la capture d'écran suivante:
...
- Entrez easyajax comme identifiant de groupe et DWREasyAjax comme identifiant d'artefact. En cliquant sur Terminer, Eclipse crée un nouveau projet Web. La capture d'écran suivante montre le projet généré et la hiérarchie du répertoire.
- Avant de commencer à faire quoi que ce soit d'autre, nous devons copier DWR sur notre application Web. Toutes les fonctionnalités DWR sont présentes dans le fichier dwr.jar, et nous copions simplement cela dans le WEB-INF | répertoire lib.
Quelques fichiers sont remarquables: web.xml et geronimo-web.xml. Ce dernier est généré pour le serveur d'applications Geronimo, et nous pouvons le laisser tel quel. Eclipse dispose d'un éditeur pour afficher le contenu de geronimo-web.xml lorsque nous double-cliquez sur le fichier.
Configuration de l'application Web
La racine de contexte vaut la peine d'être notée (visible dans la capture d'écran ci-dessus). Nous en aurons besoin lorsque nous testerons l'application.
L'autre fichier XML, web.xml, est très important, comme nous le savons tous. Ce fichier XML contiendra la définition de servlet DWR et d'autres paramètres d'initialisation possibles. Le code suivant montre le contenu complet du fichier web.xml que nous allons utiliser:
<? xml version = "1.0" encoding = "UTF-8"?>
<xmlns d'application web: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://java.sun.com/xml/ns/javaee" xmlns: web = "http : //java.sun.com/xml/ns/javaee/web-app_2_5.xsd "xsi: schemaLocation =" http://java.sun.com/xml/ns/javaee http: // java.
sun.com/xml/ns/javaee/web-app_2_5.xsd "
id = "WebApp_ID" version = "2.5">
<nom d'affichage> DWREasyAjax </ display-name>
<servlet>
<nom d'affichage> Servlet DWR </ display-name>
<nom-du-servlet> dwr-invoker </ nom-du-servlet>
<servlet-class> org.directwebremoting.servlet.DwrServlet
</ servlet-class>
<init-param>
<nom-param> déboguer </ param-name>
<param-value> true </ param-value>
</ init-param>
</ servlet>
<servlet-mapping>
<nom-du-servlet> dwr-invoker </ nom-du-servlet>
<url-pattern> / dwr / * </ url-pattern>
</ servlet-mapping>
<welcome-file-list>
<fichier de bienvenue> index.html </ welcome-file>
<fichier de bienvenue> index.htm </ welcome-file>
<fichier de bienvenue> index.jsp </ welcome-file>
<fichier de bienvenue> default.html </ welcome-file>
<fichier de bienvenue> default.htm </ welcome-file>
<fichier de bienvenue> default.jsp </ welcome-file>
</ welcome-file-list>
</ web-app>
Nous avons déjà vu la définition de servlet dans le chapitre 3, dans la section sur la configuration. Nous utilisons le même paramètre debug-init ici. Le mappage de servlet est couramment utilisé / dwr / *.
Nous nous souvenons que DWR ne peut pas fonctionner sans le fichier de configuration dwr.xml. Nous devons donc créer le fichier de configuration. Nous utilisons Eclipse pour créer un nouveau fichier XML dans le répertoire WEB-INF. Ce qui suit est requis pour le squelette de l'interface utilisateur. Il inclut déjà l'élément allow pour notre menu basé sur DWR.
<? xml version = "1.0" encoding = "UTF-8"?>
<! DOCTYPE dwr PUBLIC
"- // GetAhead Limited // DTD Direct Web Remoting 2.0 // FR" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator = "new" javascript = "HorizontalMenu">
<param name = "class" value = "samples.HorizontalMenu" />
</ create>
</ allow>
</ dwr>
Dans l'élément allow, il y a un créateur pour la classe Java du menu horizontal que nous allons implémenter ici. Le créateur que nous utilisons ici est le nouveau créateur, ce qui signifie que DWR utilisera un constructeur vide pour créer des objets Java pour les clients. Le paramètre nommé class contient le nom de classe complet.
Développer l'application Web
Puisque nous avons déjà défini le nom de la classe Java qui sera utilisée pour créer le menu, la prochaine chose à faire est de l'implémenter. L'idée derrière la classe HorizontalMenu est qu'elle est utilisée pour lire un fichier de propriétés qui contient les menus qui seront sur la page Web.
Nous ajoutons des propriétés à un fichier nommé dwrapplication.properties, et nous le créons dans le même package-échantillons que la classe HorizontalMenu. Le fichier de propriétés pour les éléments de menu est le suivant:
menu.1 = Tables et listes, TablesAndLists menu.2 = Complétion de champs, FieldCompletion
La syntaxe de la propriété de menu est qu'elle contient deux éléments séparés par une virgule. Le premier élément est le nom de l'élément de menu. Ceci est visible pour l'utilisateur. Le second est le nom du fichier de modèle HTML qui contiendra le contenu de la page de l'élément de menu.
La classe contient une seule méthode, qui est utilisée à partir de JavaScript et via DWR pour récupérer les éléments de menu. L'implémentation complète de la classe est montrée ici:
échantillons d'emballage;
import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Properties; import java.util.Vector;
Classe publique HorizontalMenu {public HorizontalMenu () {
}
public Liste <String> getMenuItems () throws IOException {Liste <String> menuItems = new Vecteur <String> (); InputStream est = this.getClass (). GetClassLoader ().
getResourceAsStream (
"samples / dwrapplication.properties"); Propriétés appProps = new Properties (); appProps.load (est);
est proche();
pour (int menuCount = 1; true; menuCount ++) {
String menuItem = appProps.getProperty ("menu." + MenuCount); if (menuItem == null) {
Pause;
}
menuItems.add (menuItem);
}
return menuItems;
}
}
La mise en œuvre est simple. La méthode getMenuItems () charge les propriétés à l'aide de la méthode ClassLoader.getResourceAsStream (), qui recherche le chemin de la classe pour la ressource spécifiée. Ensuite, après le chargement des propriétés, une boucle for est utilisée
faire une boucle sur les éléments de menu, puis une liste d'objets String est renvoyée au client. Le client est la fonction de rappel JavaScript que nous verrons plus tard. DWR convertit automatiquement les objets List of String en tableaux JavaScript, donc nous n'avons pas à nous en préoccuper.
Test de l'application Web
Nous n'avons pas encore complété de code client, mais testons le code quand même. Les tests utilisent l'environnement de test Geronimo.
- Le menu contextuel du projet a le menu Exécuter en tant que que nous utilisons pour tester l'application comme indiqué dans la capture d'écran suivante:
- Exécuter sur le serveur ouvre un assistant pour définir une nouvelle exécution du serveur. La capture d'écran suivante montre que l'environnement de test Geronimo a déjà été configuré et que nous cliquons simplement sur Terminer pour exécuter l'application. Si l'environnement de test n'est pas configuré, nous pouvons en définir un nouveau manuellement dans cette boîte de dialogue:
- Après avoir cliqué sur Terminer, Eclipse démarre l'environnement de test Geronimo et notre application avec. Lorsque le serveur démarre, l'onglet Console dans Eclipse nous informe qu'il a été démarré.
L'onglet Serveurs indique que le serveur est démarré et que tout le code a été synchronisé, c'est-à-dire que le code est le plus récent (la synchronisation se produit chaque fois que des modifications sont enregistrées sur certains fichiers déployés). le serveur. La seule application que nous testons ici est visible dans l'onglet Serveurs.
Maintenant vient la partie intéressante - qu'allons-nous tester si nous n'avons pas vraiment implémenté quelque chose? Si nous regardons le fichier web.xml, nous verrons que nous avons défini un paramètre d'initialisation. Le paramètre Debug est true, ce qui signifie que DWR génère des pages de test pour nos classes Java distantes. Nous pointons simplement le navigateur (Firefox dans notre cas) vers l'URL ... / dwr et la page suivante s'ouvre:
Cette page affichera une liste de toutes les classes que nous permettons d'être distantes. Lorsque nous cliquons sur le nom de la classe, une page de test s'ouvre comme dans la capture d'écran suivante:
C'est une page intéressante. Nous voyons toutes les méthodes autorisées, dans ce cas, toutes les méthodes de classe publique puisque nous n'avons pas spécifiquement inclus ou exclu quoi que ce soit. Les plus importants sont les éléments de script que nous devons inclure dans nos pages HTML. DWR ne sait pas automatiquement ce que nous voulons dans nos pages web,
nous devons donc ajouter le script inclut dans chaque page où nous utilisons DWR et une fonctionnalité à distance.
Ensuite, il y a la possibilité de tester des méthodes à distance. Lorsque nous testons notre propre méthode, getMenuItems (), nous voyons une réponse dans une boîte d'alerte:
Le tableau dans la zone d'alerte de la capture d'écran est le tableau JavaScript que DWR renvoie à partir de notre méthode.
Développement de pages Web
L'étape suivante consiste à ajouter les pages Web. Notez que nous pouvons laisser l'environnement de test en cours d'exécution. Chaque fois que nous modifions le code de l'application, il est automatiquement publié pour tester l'environnement. Nous n'avons donc pas besoin d'arrêter et de démarrer le serveur chaque fois que nous apportons des modifications et que nous souhaitons tester l'application.
La feuille de style CSS provient de la bibliothèque CSS Dynamic Drive. Le fichier s'appelle styles.css et se trouve dans le répertoire WebContent d'Eclipse IDE. Le code CSS est comme indiqué:
…
/*URL: http://www.dynamicdrive.com/style/ */
.basictab{ padding: 3px 0;
margin-left: 0;
font: bold 12px Verdana; border-bottom: 1px solid gray; list-style-type: none;
text-align: left; /*set to left, center, or right to align the menu as desired*/
}
.basictab li{ display: inline; margin: 0;
}
.basictab li a{
text-decoration: none; padding: 3px 7px; margin-right: 3px; border: 1px solid gray; border-bottom: none;
background-color: #f6ffd5; color: #2d2b2b;
}
.basictab li a:visited{ color: #2d2b2b;
}
.basictab li a:hover{ background-color: #DBFF6C; color: black;
}
.basictab li a:active{ color: black;
}
.basictab li.selected a{ /*selected tab effect*/ position: relative;
top: 1px;
padding-top: 4px; background-color: #DBFF6C; color: black;
}
Ce CSS est montré pour l'amour de l'achèvement, et nous n'entrerons pas dans les détails des feuilles de style CSS. Il suffit de dire que CSS fournit une excellente méthode pour créer des sites Web avec une bonne présentation.
L'étape suivante est la page Web actuelle. Nous créons une page index.jsp, dans le répertoire WebContent, qui aura le menu ainsi que les fonctions JavaScript pour nos échantillons. Il convient de noter que bien que tout le code JavaScript soit ajouté à
une seule page JSP ici dans cet exemple, dans les projets "réels" il serait probablement plus utile de créer un fichier séparé pour les fonctions JavaScript et d'inclure le fichier JavaScript dans la page HTML / JSP en utilisant un extrait de code comme ceci:
<script type = "text / javascript" src = "monjavascriptcode / HorizontalMenu.js" />.
Nous ajouterons des fonctions JavaScript plus tard pour chaque échantillon. Ce qui suit est le code JSP qui affiche le menu en utilisant la classe HorizontalMenu déconnectée.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859- 1">
<link href="styles.css" rel="stylesheet" type="text/css"/>
<script type='text/javascript' src='/DWREasyAjax/dwr/engine.js'></ script>
<script type='text/javascript' src='/DWREasyAjax/dwr/util.js'></ script>
<script type='text/javascript' src='/DWREasyAjax/dwr/interface/ HorizontalMenu.js'></script>
<title>DWR samples</title>
<script type="text/javascript">
function loadMenuItems()
{
HorizontalMenu.getMenuItems(setMenuItems);
}
function getContent(contentId)
{
AppContent.getContent(contentId,setContent);
}
function menuItemFormatter(item)
{
elements=item.split(',');
return '<li><a href="#" onclick="getContent(\''+elements[1]+'\ ');return false;">'+elements[0]+'</a></li>';
}
function setMenuItems(menuItems)
{
menu=dwr.util.byId("dwrMenu"); menuItemsHtml='';
for(var i=0;i<menuItems.length;i++)
{
menuItemsHtml=menuItemsHtml+menuItemFormatter(menuItems[i]);
}
menu.innerHTML=menuItemsHtml;
}
function setContent(htmlArray)
{
var contentFunctions=''; var scriptToBeEvaled=''; var contentHtml='';
for(var i=0;i<htmlArray.length;i++)
{
var html=htmlArray[i]; if(html.toLowerCase().indexOf('<script')>-1)
{
if(html.indexOf('TO BE EVALED')>-1)
{
scriptToBeEvaled=html.substring(html.indexOf('>')+1,
html.indexOf('</'));
}
else
{
eval(html.substring(html.indexOf('>')+1,html.indexOf('</'))); contentFunctions+=html;
}
}
else
{
contentHtml+=html;
}
}
contentScriptArea=dwr.util.byId("contentAreaFunctions"); contentScriptArea.innerHTML=contentFunctions; contentArea=dwr.util.byId("contentArea"); contentArea.innerHTML=contentHtml; if(scriptToBeEvaled!='')
{
eval(scriptToBeEvaled);
}
}
</script>
</head>
<body onload="loadMenuItems()">
<h1>DWR Easy Java Ajax Applications</h1>
<ul class="basictab" id="dwrMenu">
</ul>
<div id="contentAreaFunctions">
</div>
<div id="contentArea">
</div>
</body>
</html>
Cette JSP est notre interface utilisateur. Le HTML est juste du HTML normal avec un élément de tête et un élément de corps. La tête comprend une référence à une feuille de style et aux fichiers JavaScript DWR, engine.js, util.js, et notre propre HorizontalMenu.js. L'util. Le fichier js est facultatif, mais comme il contient des fonctions très utiles, il peut être inclus dans toutes les pages web où nous utilisons les fonctions de util.js.
L'élément body a un espace réservé contentArea pour les pages de contenu juste en dessous du menu. Il contient également la zone de contenu pour les fonctions JavaScript pour un contenu particulier. L'élément de corps onload-event exécute loadMenuItems ()
fonction lorsque la page est chargée. La fonction loadMenuItems () appelle la méthode distante de la classe Java HorizontalMenu. Le paramètre du HorizontalMenu. getMenuItems () La fonction JavaScript est la fonction de rappel appelée par DWR lorsque la méthode Java a été exécutée et qu'elle renvoie des éléments de menu.
La fonction setMenuItems () est une fonction de rappel pour la fonction loadMenuItems () mentionnée dans le paragraphe précédent. Lors du chargement des éléments de menu, la méthode distante Horizontal.getMenuItems () renvoie les éléments de menu sous la forme d'une liste de chaînes en tant que paramètre de la fonction setMenuItems (). Les éléments de menu sont formatés à l'aide de la fonction d'aide de menuItemFormatter ().
La fonction menuItemFormatter () crée des éléments li de textes de menu. Les menus sont formatés en tant que liens (un href) et ils ont un événement onclick qui a un appel de fonction à la fonction getContent, qui à son tour appelle la fonction AppContent.getContent ().
L'AppContent est une classe Java à distance, que nous n'avons pas encore implémentée, et son but est de lire le code HTML à partir d'un fichier basé sur l'élément de menu sur lequel l'utilisateur a cliqué. L'implémentation de AppContent et les pages de contenu sont décrites dans la section suivante.
La fonction setContent () définit le contenu HTML dans la zone de contenu et évalue également les options JavaScript contenues dans le contenu à insérer dans la zone de contenu (ce n'est pas très utilisé, mais il est là pour ceux qui en ont besoin).
Notre interface utilisateur dynamique ressemble à ceci:
Notez la fenêtre Firebug en bas de l'écran du navigateur. La console Firebug dans la capture d'écran montre une requête POST à notre méthode HorizontalMenu.getMenuItems (). Les autres fonctionnalités de Firebug sont extrêmement utiles pendant le travail de développement, et nous trouvons utile que Firebug ait été activé tout au long du travail de développement.
Fonctions de rappel
Nous avons vu notre première fonction de callback en paramètre dans la fonction HorizontalMenu.getMen uItems (setMenuItems), et comme les callbacks sont un concept important dans DWR, il serait bon d'en discuter un peu plus maintenant que nous en avons vu la première utilisation.
Les rappels sont utilisés pour fonctionner sur les données renvoyées à partir d'une méthode distante. Comme DWR et AJAX sont asynchrones, les valeurs de retour typiques dans les appels RPC (Remote Procedure Calls), comme dans les appels Java, ne fonctionnent pas. DWR masque les détails de l'appel des fonctions de rappel et gère tout en interne à partir du moment où nous renvoyons une valeur de la méthode Java distante à la réception de la valeur renvoyée au
fonction de rappel.
Deux méthodes sont recommandées lors de l'utilisation des fonctions de rappel.
Nous avons déjà vu la première méthode dans l'appel de fonction HorizontalMenu.getMenuItems (setMenuItems). Souvenez-vous qu'il n'y a pas de paramètres dans la méthode Java getMenuItems (), mais dans l'appel JavaScript, nous avons ajouté le nom de la fonction de rappel à la fin de la liste des paramètres. Si la méthode Java a des paramètres, l'appel JavaScript est similaire à CountryDB.getCountries (selectedLetters, setCountryRows), où selectedLetters est le paramètre d'entrée pour la méthode Java et setCountryRows est le nom de la fonction de rappel (nous verrons l'implémentation plus tard). ).
La seconde méthode d'utilisation des rappels est un objet de métadonnées dans l'appel JavaScript distant. Un exemple (une implémentation complète est montrée plus loin dans ce chapitre) est montré ici:
CountryDB.saveCountryNotes (ccode, newNotes, {callback: function (nouvelles notes)
{
// corps de la fonction ici
}
});
Ici, la fonction est anonyme et son implémentation est incluse dans l'appel JavaScript à la méthode Java distante. Un avantage ici est qu'il est facile de lire le code, et le code est exécuté immédiatement après avoir obtenu la valeur de retour de la méthode Java. L'autre avantage est que nous pouvons ajouter des options supplémentaires à l'appel.
Les options supplémentaires incluent le gestionnaire de délai et d'erreur, comme indiqué dans l'exemple suivant:
CountryDB.saveCountryNotes (ccode, newNotes, {callback: function (nouvelles notes)
{
// corps de la fonction ici
},
timeout: 10000,
errorHandler: function (errorMsg) {alert (errorMsg);}
});
Il est également possible d'ajouter une fonction de rappel aux méthodes Java qui ne renvoient pas de valeur. L'ajout d'un rappel à des méthodes sans valeur de retour serait utile pour obtenir une notification lorsqu'un appel distant a été effectué.
Épilogue
Notre premier échantillon est prêt, et c'est aussi la base pour les échantillons suivants. Nous avons également examiné comment les applications sont testées dans l'environnement Eclipse.
