Lorsque le développeur valide une fiche, un traitement de génération du dictionnaire est activé pour produire le fichier xml.
La validation génère une nouveau dictionnaire XML des paramètres XTEND.
Le nouveau dictionnaire n'est pris en compte automatiquement sur reload/F5 de la page HTML dans le navigateur que si l'option de la fiche de paramétrage du site, fonction Sites Web(GESAYS)'Technique\Vérifier mises à jour\Dictionnaire web' est cochée.
Sinon il faut forcer le rechargement du dictionnaire avec l'url :
'http://hostname:port/xtend/svc/SolutionX3/DossierX3/SiteXtend/admin/reposit/reload'
Il est conseillé de valider l'intégralité du site via la fonction afin de reconstruire le dictionnaire du serveur XTEND via la fonction Validation site Web(AYTFCYGEN).
Bien vérifier que le site XTEND est publié, c'est à dire le champ 'Publié le site' de la fiche 'Site web' est coché.
Techniquement le serveur XTEND accède aux fichiers X3 via le serveur HTTP (Apache) qui est installé par défaut sur la machine qui héberge le serveur X3 principal.
Le répertoire racine est le répertoire X3_PUB de la solution.
La détection des mise à jour se fait sur lecture du 'TimeStamp' (date de dernière modification) du ficher.
Le serveur XTEND lit les fichiers XML et constitue une base de données en mémoire pour optimiser l'accès aux paramètres.
Lors du chargement, XTEND contrôle la cohérence du dictionnaire et génère une exception en cas d'erreur.
Par défaut le dictionnaire et les menus locaux sont stockés sur le serveur X3.
Les paramètres console xtend.server.reposit.local=off et xtend.server.menux3.local=off permettent de définir une localisation des fichier en local du serveur X3WEB (optimisation).
Dans cas il faut copier les répertoires dictionnaire et/ou menu locaux sous \WebData\LOCAL\X3SOLUTION\X3_PUB\.
WebData est le répertoire 'Data' défini lors de l'installation du serveur X3WEB.
Par défaut les pages et toutes les ressources du projet HTML sont stockées sur le serveur X3 dans le répertoire:
/X3SOL/dossiers/X3_PUB/X3FOLDER/X_TEND/X_HTML/ASAMPLE/LANG/ (LANG étant le code langue du site).
Le développeur doit penser à 'uploader' les pages HTML sur le serveur X3 avant de les tester dans son navigateur.
Sous unix il faut bien vérifier que tous les fichiers du répertoire HTML ont les droits minimum en 'lecture' pour tous les utilisateurs.
Le processus de lecture des pages et de détection des modifications est identique à celui du dictionnaire.
Un paramètre du site XTEND permet d'activer/désactiver les vérifications des mises à jour.
Si la vérification est désactivée il faut utiliser l'url de rechargement du dictionnaire pour forcer le serveur XTEND à prendre en compte les modifications des pages.
Une page web est un fichier texte qui contient des balises HTML dans lequelles le développeur a ajouté les tokens XTEND.
Après chargement de la page, le serveur XTEND lit le contenu et interprète le HTML et les tokens (parsing) pour constituer une représentation en mémoire de la page sous la forme d'un arborescente d'objets (DOM).
Chaque objet représente un token et implémente une méthode de calcule du HTML (computeHtml).
L'arborescence des tokens est visible dans la trace XTEND:
++ correspond au niveau - CXtdHtmBuild* est la classe de l'objet
+CXtdHtmBuildDom - XTEND
++CXtdHtmBuildNodeHtml - HTML
++CXtdHtmBuildTagHead - <HEAD
+++CXtdHtmBuildTagBase - <BASE
++CXtdHtmBuildAdxScriptLibrary - ALIBJS
++CXtdHtmBuildTagHeadEnd - </HEAD
++CXtdHtmBuildTagBody - <BODY
++CXtdHtmBuildTagForm - <FORM
++CXtdHtmBuildAdxTagAnchor - AHOME
++CXtdHtmBuildAdxTagAnchor - AABOUT
++CXtdHtmBuildAdxCND - ADISPUSERLOGGEDIN
+++CXtdHtmBuildAdxTagAnchor - AUSERACCOUNT
+++CXtdHtmBuildAdxTagAnchor - ADLKLOGOUT
++CXtdHtmBuildAdxCND - ADISPUSERLOGGEDIN
+++CXtdHtmBuildAdxTagAnchor - ALOGIN
...
Le parser HTML du serveur XTEND est compatible avec la version HTML 4.01 (DTD HTML 4.01 Transitional).
La seule contrainte qu'impose XTEND pour le design HTML est de n'utiliser qu'un seul formulaire HTML qui encapsule tout le corps (body) de la page HTML.
<body><form> Contenu du body </form></body>
Pour calculer dynamiquement le contenu de la page HTML, le serveur XTEND effectue les opération suivantes:
Pour les interfaces de type Accès données:
Pour les interfaces de type Action:
Si le token est un champ:
Si le token est un lien dynamique:
Si le token est un bloc:
Si le token est un bloc conditionné:
La méthode de calcul du HTML dépend du type de token et du tag HTML dans lequel est il est inséré.
Le HTML calculé est fonction du type de token et du tag HTML dans lequel il est inséré.
Remplace le contenu du tag par la valeur du champ
<td adx="myField"></td> ---> <td>Valeur</td>
Sélectionne l'option qui correspond à la valeur du champ en générant l'attribut selected
Exemple si la valeur de myField est FR l'option value="FR" et sélectionnée (attribut selected)
<select adx="myField">
<option value="AT">Austria</option>
<option value="FR">France</option>
</select>
<!--GENERE-->
<select adx="myField">
<option value="AT">Austria</option>
<option selected value="FR">France</option>
</select>
Génère l'URL qui permet au navigateur de lire l'image
<img adx="COUNTRYFLAG">
<!--GENERE-->
<img src="/xtend/data/exp(expires,index)/remote/SOL/FLDR/X_TEND/X_HTML/SITE/FRA/FLAGS/BE.gif"/>
Si le token n'a pas d'action associée (méthode GET) calcule l'attribut href du tag
Sinon (méthode POST) traite le tag comme un bouton (ci-dessous)
<a adx="MyDynLink">Logout</a>
<!--GENERE d'URL'-->
<a href="http://host:port/xtend/page?DLK=MyDynLink&SOL=SOL...">Logout</a>
Calcule la fonction JavaScript xtdDoDlk et l'insère dans l'attribut 'onClick'
Les paramètres sont contextuels et sont traités par la librarie XTEND
<input type="button" adx="MyDLK" value="Créer">
<!--GENERE L'ATTRIBUT ONCLICK'-->
<input type="button"
onclick="xtdDoDlk(this,'MyDLK',null,null,null,0,null,event,true,'',false,null,true);"
value="Créer"/>
Cette fonction est générée par XTEND dans l'atribut onClick pour les liens dynamiques qui ont une action ou une sélection associée.
Elle déclenche le processus JavaScript XTEND de traitement des actions utilisateur.
Elle permet aussi de retrouver le contexte de données (aCtxTag,aLineIdx) du lien dynamique en particulier pour les tokens générés dans les lignes des blocs.
function xtdDoDlk(aElmt,aDlk,aProtocol,aBlkId,aCtxTag,aLineIdx,aUrlAdd,aEvent,aSubmit,
aAutoId,aForceAcceptReload,aForceSelBlock,aCheckWebFields)
{/*
aElmt: Object JavaScript sur lequel l'utilisateur a cliqué
aDlk: Code du lien dynamique cliqué
aProtocol: Si !=null force le protocole (https,http) pour ce lien
aBlkId: Code du bloc de référence si adx='MyBlocRefence.MyLink'
aCtxTag: Identifiant du contexte de donnée (si action avec paramètres de type champs XTEND)
aLineIdx: Index de la ligne si le token est placé dans un bloc {{multi}}
aUrlAdd: Contient la valeur du paramètres HTML xanchor adx="MyLink:xanchor=#section"
aEvent: Contient l'objet événement JavaScript
aSubmit: True pour soumettre le formulaire
aAutoId: Id généré par XTEND si adx="MyLink:xautoid"
aForceAcceptReload:True pour accepter le reload (F5)
aForceSelBlock:Id du bloc qui traite la requête si != AMAIN
aCheckWebFields:True pour contôler les champs web
*/
}
Le contexte de données de la page est stocké dans la page elle même dans un tag span masqué.
Il contient toutes les valeurs des champs (type 'Token champ') utilisés en paramètre des actions des lien dynamiques de la page.
Cette méthode permet de gérer très efficacement le retour arrière via la fonction 'Back' du navigateur.
<span id="xtdctx" style="display: none; clear: both;">
XML qui contient le contexte de la page
</span>
Pour bien comprendre le fonctionnement XTEND il est nécessaire de détailler le mécanisme de résolution de la valeur d'un champ par le serveur XTEND.
Le serveur XTEND maintient un contexte de données qui est géré dans une pile (ou stack) de blocs de données (entités).
Ce contexte de données est constitué:
Etat initial
Lorsque la construction de la page démarre, le contexte de données ne contient que les données de la session.
Traitement des blocs
Lorsque le serveur XTEND traite un bloc, il effectue une itération sur toutes les entités sélectionnées.
Pour chaque entité il effectue le traitement suivant:
1. Empile (push) la donnée (entité) dans le contexte de données
-->L'entité est positionnée au sommet de la pile (top) et sera traitée en premier lors de la résolution de la valeur d'un champ
2. Appelle la méthode de construction du HTML des tokens fils
-->Ce mécanisme est récursif et permet d'empiler les blocs
3. Dépile l'entité
-->Après avoir traité tous les tokens fils le serveur dépile l'entité avant de traiter la suivante
L'entité qui est au sommet de la pile est adressée par le bloc ACURRENT.
Par exemple un critère de sélection 'CODE=ACURRENT.CODE' dans un lien dynamique indique qu'il faut sélectionner l'élément de la ligne courante
Le principe de résolution de la valeur d'un champ consiste à :
1. parcourir la pile des entités du haut (top) vers le bas (bottom)
2. s'arrêter lorsque l'entité lue contient un champ de même nom
Si un champ a été trouvé XTEND renverra la valeur de ce champ sinon il renverra une valeur vide.
L'exemple ci dessous montre l'état de la pile avec un bloc de 'fond' mono-enregistrement (BLOCMONO) deux blocs multi-enregistrements imbriqués (BLOCMULTI1, BLOCMULTI2).
Le premier bloc multi est positionné sur la 2eme ligne et le deuxième bloc (BLOC2) est positionné sur la 3eme ligne.
<!adx="BLOCMONO">
<!adx="BLOCMULTI1">
<!adx="BLOCMULTI2">
<span adx="MyField">
<!adx="BLOCMULTI2">
<!adx="BLOCMULTI1">
<!adx="BLOCMONO">
Pile | Ordre |
ASESSION | 3 - Bottom |
ENTITE_BLOCMONO | 2 |
ENTITE_BLOCMULTI1_LIGNE2 | 1 |
ENTITE_BLOCMULTI2_LIGNE3 | 0 - Top |
Pour résoudre la valeur du champ MyField le serveur XTEND va vérifier la présence du champ MyField dans les entités suivant l'ordre ci-dessous:
1. ENTITE_BLOCMULTI2_LIGNE3
2. ENTITE_BLOCMULTI1_LIGNE2
3. ENTITE_BLOCMONO
4. ASESSION
Le principe de résolution de la valeur est le même pour :
Pour calculer la valeur d'un champ pour une entité donnée il faut utiliser les syntaxes suivantes :
Le contexte session est constitué des différents blocs de données ci-dessous.
La résolution de la valeur d'un champ est effectuée suivant l'ordre de présentation des blocs dans la liste.
1. AUSERINF - Informations utilisateur signé
2. AUSERVAR - Variables utilisateur
3. ASITE - Document site
4. AMESS - Messages utilisateur
5. AUSERCRIT - Critères utilisateur
6. ASYSVAR - Variables systèmes
7. ACONST - Tokens champ de type constantes
Les requête http
Dans l'architecture X3WEB qui héberge le serveur XTEND nous avons 3 couches applicatives:
1. le serveur frontal Apache HTTP qui traite les requêtes HTTP
2. le serveur Apache Tomcat qui héberge les 'applications web'
3. l'application web XTEND
Les requêtes http à destination de l'application web XTEND sont identifiée par l'URI qui commence par /xtend/*.
Le 'path' de l'application web XTEND est paramétrable via la console via le paramètre avancé:
xtend.server.virtualpath.context=xtend
L'application web sait traiter un certain nombre de requêtes (servlets) identifiées par le 2eme paramètre de l'URI /xtend/servlet/ :
Le protocole HTTP propose différentes méthodes ou commandes qui spécifient le type d'action qu'effectue la requête.
Le serveur XTEND ne répond qu'au méthodes GET et POST qui ont la signification suivante:
Un lien dynamique utilise par défaut la méthode POST si une sélection ou une action lui est associée.
Cette méthode soumet (submit) le formulaire HTML <form></form> de la page via l'appel de la fonction JavaScript xtdDoDlk.
Cette fonction calcule les paramètres du lien dynamique (xml) et les envoie dans un champ input hidden.
Le serveur reçoit toutes les informations dont il a besoin pour traiter l'action ou la sélection associée au lien dynamique sur lequel il a cliqué (données des champs du formulaire et contexte calculé par le client).
Un lien dynamique peut utiliser la méthode GET si il effectue seulement un débranchement vers une page ou si il n'a pas de paramètre d'action ou de sélection à calculer.
Cette méthode ne soumet pas le formulaire HTML mais débranche le navigateur vers une URL qui ne contient que les paramètres de base (lien, solution, dossier, site, langue).
Seule la méthode GET est compatible avec les moteurs de recherche (web crawlers).
Pour des raisons de sécurité, l'utilisateur du web peut passer par l'intermédiaire d'un reverse proxy pour accéder aux applications de serveurs internes.
L'utilisation d'un reverse proxy permet aussi de masquer aux utilisateur l'adresse réelle d'un serveur et facilite la maintenance d'un site.
En cas d'arrêt d'un serveur on pourra rediriger temporairement les requêtes vers un autre serveur de façon transparente pour le client.
Pour définir un 'reverse proxy' d'alias proxyxtend dans le serveur Apache du serveur X3WEB hostproxy qui "redirige" les requêtes XTEND vers hostxtend on utilise la configuration suivante.
Créer un 'virtual host' sur le port 80
<VirtualHost _default_:80>
<Location "/proxyxtend/">
ProxyPass "http://hostxtend:28980/"
ProxyPassReverse "http://hostxtend:28980/"
ProxyPassReverseCookieDomain "hostxtend" "hostproxy"
ProxyPassReverseCookiePath "/xtend" "/proxyxtend/xtend"
</Location>
</VirtualHost>
<VirtualHost _default_:443>
...
ProxyRequests Off
SSLProxyEngine on
ProxyPreserveHost On
<Location "/proxyxtend/">
ProxyPass "https://hostxtend:28943/"
ProxyPassReverse "https://hostxtend:28943/"
ProxyPassReverseCookieDomain "hostxtend" "hostproxy"
ProxyPassReverseCookiePath "/xtend" "/proxyxtend/xtend"
SSLRequireSSL
</Location>
...
</VirtualHost>
Lorsque le serveur Apache hostproxy reçoit l'url http://hostproxy/proxyxtend/xtend/page/*.
Il va se comporter comme un mandataire et effectuer pour le client la requête http://hostxtend/xtend/page/* vers le serveur XTEND.
Le serveur XTEND qui va calculer la page HTML à renvoyer vers le client doit prendre en compte le reverse proxy pour générer des URL'S qui soient correctes pour le client final (le navigateur).
Dans notre cas, XTEND doit génére des URL's en /proxyxtend/xtend/*.
Il doit donc impérativement tenir compte de la présence du reverse proxy pour calculer l'URL.
La méthode utilisée par XTEND est la suivante:
-1- Déclaration des reverse proxies
Déclaration des ports http et https des 'reverse proxies' via la console d'administration en modifiant les paramètres avancés suivants:
# Configuration reverse proxies
xtend.server.gensetup.proxies.hosts= hostproxy1 hostproxy2
xtend.server.gensetup.proxies.portshttp= 80 80
xtend.server.gensetup.proxies.portshttps= 443 443
-2- Lecture du 'Referer' HTTP
Le header HTTP Referer contient l'url qui a été utilisée par le client pour joindre le serveur.
Le serveur XTEND analyse cette URL et en déduit la présence d'un reverse proxy si /xtend/ est préfixée par une valeur (exemple /proxyxtend/xtend/).
La configuration précédente permet de gérer les changement de protocole http->https ou inversement. Le serveur XTEND doit obligatoirement connaître les ports http et https du reverse proxy.
Pour fonctionner correctement avec un reverseproxy le serveur XTEND doit donc obligatoirement connaitre le 'Referer' http et les ports http et https du (premier) reverse proxy.
La paramètre de configuration xtend.server.gensetup.http.askreferer=on/off (on par défaut) permet d'activer ou désactiver ce mécanisme.
Le header http 'Referer' n'est pas toujours présent, en particulier lorsqu'on saisit l'adresse dans la barre dresse du navigateur.
Si le header http 'Referer' n'est pas présent dans la requête, le serveur XTEND envoie vers le navigateur un formulaire vide avec réponse automatique (transparent pour l'utilisateur) qui dans la plupart des cas renvoie le 'Referer'.
Si la tentative échoue et que le 'Referer' n'est pas renvoyé, le serveur XTEND ne pourra pas prendre en compte la présence d'un reverse proxy.
Le protocole de communication entre le navigateur web et le serveur HTTP est le protocole HTTP qui est "sans état".
Le serveur HTTP ne conserve aucune trace du client après traitement de la requête.
Tout se passe comme si la connexion entre le client et le serveur était coupée après chaque requête.
Le mode de fonctionnement est complètement différent du mode client/serveur (client X3) qui maintient une connexion active avec le serveur X3 pendant toute la durée de la session.
Pour développer des applications web nous avons besoins de faire le lien entre différentes requêtes pour les associer à un même client.
Ce lien est effectué via l'utilisation des cookies HTTP.
Un cookie est créé à l'initiative du serveur lorsque celui-ci envoie au client un instruction 'set cookie' dans l'entête HTTP.
Le cookie est ensuite renvoyé par le client dans l'entête HTTP de toutes les requêtes à destination de ce serveur.
Instruction
Set-Cookie: JSESSIONID=3C9B3EF39FB53069ACB02B6ADA5551A1; Path=/xtend
Path permet de filter les cookies à destination du serveur
Dans notre cas JSESSIONID sera renvoyé dans toutes les requêtes dont l'URI commence /xtend/ (http://host:port/xtend/....)
L'identification par cookie (et donc le fonctionnement de l'application web) ne fonctionne que si le navigateur autorise les cookies de type session (non sauvegardés).
C'est généralement le réglage par défaut des navigateurs web
La notion de 'client' diffère suivant les navigateurs et dépend de la manière dont ils gèrent les cookies.
La session utilisateur qui permet d'associer un contexte de données spécifique à chaque client est gérée par le serveur TOMCAT via la notion de servlet.
Pour identifier les requêtes et les rediriger vers la bonne session utilisateur le serveur TOMCAT gère un cookie session spécifique de code JSESSIONID.
Cookie géré par le serveur TOMCAT
Set-Cookie: JSESSIONID=3C9B3EF39FB53069ACB02B6ADA5551A1; Path=/xtend
JSESSIONID est l'identifiant de session TOMCAT
Le cookie JSESSIONID n'est pas persistant c'est à dire qu'il n'est pas conservé lorsqu'on ferme le navigateur.
L'utilisateur perd donc sa session et donc son contexte de données si il ferme son navigateur.
La session est conservée en mémoire pendant une durée paramétrable via le paramètre de configuration console :
xtend.server.gensetup.http.session.timeout
Ce paramètre indique la durée d'inactivité, en minutes, tolérée par le serveur TOMCAT pour une session utilisateur.
Si aucune activitée (requête reçue) n'est détectée pendant cette période, la session est supprimée et le contexte de données est perdu.
Le serveur XTEND gère son propre indentifiant de session via le cookie XADXID.
Ce cookie est persistant c'est à dire qu'il est sauvegardé par le navigateur (si autorisé).
Lorsque l'utilisateur ouvre son navigateur et se connecte au serveur XTEND, le cookie XADXID est envoyé dans la requête (si il existe) et le serveur essaie de retrouver la session (TOMCAT) de l'utilisateur pour le reconnecter.
Cookies gérés par le serveur XTEND
Set-Cookie XADXID=123332746651556912893670; Expires=Sat, 30-Jan-2010 14:57:46 GMT; Path=/xtend
Le paramètre de configuration console xtend.server.gensetup.http.cookie.sess.persist=on (on par défaut) permet d'activer/désactiver la gestion de la reconnexion suite à la fermeture du navigateur.
La page de reconnexion du site (facultative) permet d'informer l'utilisateur que sa session a été restaurée.
XTEND propose un mode de fonctionnement sans cookies qui propage l'identificateur de session JSESSIONID dans l'URL.
Ce mode peut être soit activé:
Le mode sans cookies augmente la taille des URL'S en ajoutant un paramètre supplémentaire:
http://ecfdalbopro:28980/xtend/page;jsessionid=E04AEF0615702B3C7E52107ED6C17D8A?DLK=DLKTESTMAPPING...
Ce mode ne permet pas l'utilisation de liens vers d'autre sites web car l'id session n'est pas propagé et la session utilisateur est perdue.
Ce paragraphe décrit le processus de traitement des requêtes HTTP par le serveur XTEND.
1. Réception de la requête HTTP
2. Filtre la requête en fonction de l'URI
3. Transfert la requête vers 'Apache TOMCAT server' via le mod_jk
mod_jk : 'module Jakarta' qui est le nom du projet de logiciels libres duquel est issu le projet TOMCAT
JkMount xtend/portal* ajp13
JkMount xtend/page* ajp13
JkMount xtend/err/* ajp13
JkMount xtend/ajax/* ajp13
JkMount xtend/x3rsrc/* ajp13
JkMount xtend/htmrsrc/* ajp13
JkMount xtend/x_protect/* ajp13
JkMount xtend/data/* ajp13
JkMount xtend/svc/* ajp13
JkMount xtend/*.jsp ajp13
1. Crée une tâche (thread) pour le traitement de la requête
2. Retrouve le service (objet servlet) identifiée par l'URI
3. Retrouve la session avec le cookie JSESSIONID
4. Appelle méthode doPost ou doGet du service
1. Initialisation
1. Si nouvelle session TOMCAT
2. Si redirection (chagement de protocole...)
3. Lectures des paramètres XTEND
2. Ouverture session
1. Mise en attente si session en cours d'utilisation par une autre requête
2. Positionnement du contexte sur le site XTEND
3. Vérification des mises à jour du dictionnaire XTEND
3. Contrôles
1. Contrôle du protocole
2. Si utilisateur signé : contrôle durée d'inactivité de la session XTEND
3. Si la page si page est protégée
Paramètre 'Accès protégé' de la fiche page
1. Contrôle des droits d'accès de l'utilisateur
2. Si l'utilisateur n'a pas les droits d'accès
4. Traitement de l'action web si une action est associée au lien dynamique
5. Affichage de la page
1. Vérification des mises à jour de la page
2. Initialisation des tokens bloc (requêtes)
3. Calcul du HTML
6. Envoie de la réponse au navigateur