initialize: function(aCaller,url,aContentType,aReturnedType,params)
{
// Traitement spécifique
// Appel de la requete Ajax de prototype.js
$super(url,options);
},
Objet appelant (voir § suivant)
Url d'appel du web service REST XTEND
ContentType des données envoyées - null autorisé
ContentType des données retournées - null autorisé
Données envoyées dans le corps de la requête - null autorisé
Toutes les classes et fonctions sont rattachée à l'objet XTENDAJAX.
C'est l'objet qui appelle la requête et qui gère le contexte d'appel dont on aura besoin pour traiter la réponse.
Cet objet doit implémenter les méthodes suivantes pour traiter les différents états de la réponse:
//------------------------------------------------
//Appel si HTTP statut est égal = 200
//response : Classe Ajax.Response
onSuccess:function(response){
},
//------------------------------------------------
//Appel si HTTP status est différent de 200
//request : Classe Ajax.Request
//exception : String ou classe Error
onFailure:function(request, exception){
},
//------------------------------------------------
//Appel sur exception JavaScript
//request : Classe Ajax.Request
onException :function(response,headerJSON){
}
Les fonction onFailure et onException sont facultatives.
Si l'objet appelant ne les implémente pas les fonctions d'affichage XTENDAJAX.displayException et XTENDAJAX.displayFailure seront appelées.
L'exemple ci-dessous appel le web service REST identifié par le paramètre aURL avec les données aData et affiche la réponse.
var wClassCaller=Class.create({
onSuccess:function(response){
response.xtdDisplay();
},
call:function(aURL,aData){
new XTENDAJAX.request(this,aURL,null,null,aData);
}
});
var wURL="http://ecfdalbopro:28980/xtend/ajax/SOLPAIE/PAIE/FDBTEST/INT/XTDLOGIN";
var wInput={
_JSONOPT:{OPTIONS:"nogroups"},
AXUSERCODE:"DIS001",
AXPWD:"adonix"
};
new wClassCaller().call(wURL,wInput);
Dans la pratique on utilise les classe de la classe XTENDWSVC.classCallerSpg de la librairie XtendAjaxWsvc.js qui facilitent le calcul de l'url et la manipulation des données.
Le paramètre response est instancié à partir de la classe Ajax.response auquel on a ajouté les méthodes spécifiques pour manipuler la réponse du serveur XTEND (XTENDAJAX.xtdExtendResponse).
{
//-------------------------------------------------
// Affiche le contenu de la réponse au format texte (XTENDAJAX.msgBox)
xtdDisplay:function(),
//-------------------------------------------------
// Tableau qui contient les messages d'erreur
xtdMsgErr:,
// Renvoie true si la réponse comporte une erreur applicative X3
xtdHasX3Error:function(),
//-------------------------------------------------
// Tableau qui contient les messages warning
xtdMsgWarning:,
//-------------------------------------------------
// Tableau qui contient les messages d'information
xtdMsgInfo:,
//-------------------------------------------------
// Tableau qui contient tous les messages
xtdMsgAll:,
//-------------------------------------------------
// ContenType de la réponse
xtdContentType:,
//-------------------------------------------------
// True si ContentType=text/plain
xtdIsText:function(),
//-------------------------------------------------
// True si ContentType=text/html
xtdIsHtml:function(),
//-------------------------------------------------
// True si ContentType=application/xml
xtdIsXml:function(),
//-------------------------------------------------
// True si ContentType=application/json
xtdIsJson:function(),
/*------------------ Réponse XML ------------------*/
//Evalue la réponse et renvoie un DOM XML (voir XtendAjaxDom.js)
xtdEvalXML,
//Contient le DOM XML créé par xtdEvalXML
xtdResponseXML:,
/*------------------ Réponse JSON------------------*/
//Evalue la réponse et renvoie un objet JSON qui représente la réponse
xtdEvalJSON:function(),
//Contient l'objet JSON créé par xtdEvalJSON
xtdResponseJSON:,
//Renvoie un Hash ($H) créé à partir d'un tableau de clés et de valeurs
xtdHash:function(aKeyArray,aValArray),
/*------- Réponse WEB SERVICE SOUS-PROGRAMME -------*/
//Evalue la réponse à un sous-programme
//-> Ajoute les méthodes spécifiques
xtdEvalJSONSpg:function(),
//Renvoie la valeur du paramètre AXPAR
AXPAR:function(aCode),
//Renvoie la valeur du paramètre AXPAR comme un entier
AXPARInt:function(aCode,aDefValue),
/*------ Réponse SOUS-PROGRAMME ACCES DONNEES -------*/
//Evalue la réponse à un web service sous-programme accès données
//-> Ajoute les méthodes spécifiques
xtdEvalJSONSpgAccess:function(),
//Nombre de records demandés
askedRecords:function(),
//Nombre total de records
totalRecords:function(),
//Nombre records renvoyés
returnedRecords:function(),
//Rang (1-N) du premier record
startRank:function(),
//True si il existe des records suivants - False si pagination terminée
hasNext:function(),
/*--------- Réponse WEB SERVICE OBJET X3 ----------*/
//Evalue la réponse à un web service objet X3
//-> Ajoute les méthodes spécifiques
xtdEvalJSONObject:function(),
//Groupe technique ADXTEC
adxADXTEC:function(aField),
//Timestamp de l'objet X3
adxTimeStamp:function(),
//UserCode X3 qui a modifié l'objet en dernier
adxUser:function(),
}
La librairie XtendAjaxWsvc.js met à disposition du développeur un ensemble de classe pour faciliter l'appel des web services REST d'XTEND de type interface.
La requête AJAX déclenche l'exécution d'un web service identifié par la fiche interface et traite directement le résultat. Le serveur XTEND ne fait qu'appeler le web service X3 et renvoyer la réponse.
Toutes les classes et fonctions sont rattachée à l'objet XTENDWSVC
/*----------------- TESTS -----------------*/
//Appel l'interface aInterfaceId avec les données aXmlData
// Affiche le résultat
testSpgXML:function(aInterfaceId,aXmlData),
//---------------------------------------------
//Appel l'interface aInterfaceId avec les données aJSONData
// Affiche le résultat
testSpgJSON:function(aInterfaceId,aJSONData),
/*----------------- CALL STATIQUE -----------------*/
//Appel l'interface sous-programme aInterfaceId avec les données aData
//Les fonctions CallBack statiques sont passées en paramètre
runSpg:function(aInterfaceId,aData,onSuccess,onFailure),
//---------------------------------------------
//Idem runSpg avec des données JSON en retour
runSpgJSON:function(aInterfaceId,aData,onSuccess,onFailure),
//---------------------------------------------
//Idem runSpg avec des données XML en retour
runSpgXML:function(aInterfaceId,aData,onSuccess,onFailure),
/*----------------- PARAMETRES D'APPEL -----------------*/
//Renvoie un objet paramètre de base XTENDWSVC.classParam
//aJSONOptions : options JSON (facultatif)
newParam:function (aJSONOptions),
//---------------------------------------------
//Renvoie un objet paramètre pour l'appel d'un web service objet X3
//Classe XTENDWSVC.newParamXtdObject
//aTimeStampX3 : le timestamp X3 de l'objet (facultatif)
newParamXtdObject:function (aTimeStampX3,aJSONOptions),
//---------------------------------------------
//Renvoie un objet paramètre pour l'appel d'un web service sous-programme
//Classe XTENDWSVC.classParamXtdSpg
newParamXtdSpg:function (aJSONOptions),
//---------------------------------------------
//Renvoie un objet paramètre pour l'appel d'un sous-programme 'accès données'
//Classe XTENDWSVC.classParamXtdSpgAccess
//aNbLines : nombre maximum de records demandés
//aStartAt : rang du 1er record
newParamXtdSpgAccess:function (aNbLines,aStartAt,aJSONOptions),
//---------------------------------------------
//Renvoie un objet paramètre pour l'appel d'une liste gauche objet X3
//Classe Hash (tableau clé/valeur)
//aNbLinesReturned : nombre lignes demandés
newParamQuery:function(aNbLinesReturned,aJSONOPtions),
//---------------------------------------------
//Renvoie un objet paramètre de type clé
//Classe Hash (tableau clé/valeur)
newParamRead:function(aJSONOPtions),
//---------------------------------------------
//Vérifie que aHash est bien un paramètre pour un query
//Présence de la clé "_COUNT" qui contient le nombre de lignes demandées
checkQueryParam:function(aHash,aReturnedCount),
Classe de base des paramètres.
XTENDWSVC.classParam=Class.create({
/---------------------------------------
//aJSONOptions : Options JSON
initialize: function(aJSONOptions),
/---------------------------------------
//Renvoie les options JSON
options:function(),
/---------------------------------------
//Ajoute un paramètre aCode avec la valeur aCode
add:function(aCode,aValue),
/---------------------------------------
//Renvoie la valeur du paramètre aCode
get:function(aCode)
)}
Classe de paramètre d'appel d'un web service sous-programme qui hérite de XTENDWSVC.classParam.
XTENDWSVC.classParamXtdSpg=Class.create(XTENDWSVC.classParam,{
/---------------------------------------
//aJSONOptions : Options JSON
initialize: function(OptionsJSON),
/---------------------------------------
//Ajout d'un parametre AXPAR
addAXPAR:function(aCode,aValue)
});
Classe de paramètre d'appel d'un web service sous-programme de type 'Accès données' qui hérite de XTENDWSVC.classParamXtdSpgAccess.
XTENDWSVC.classParamXtdSpgAccess=Class.create(XTENDWSVC.classParamXtdSpg,{
/---------------------------------------
//aJSONOptions : Options JSON
//aNbLines : nombre maximum de records demandés
//aStartAt : rang du 1er record
//Met à jour les paramètres '$REC_STARTAT','$TOTAL_COUNT','$RET_COUNT','$HAS_NEXT'
initialize: function(aNbLines,aStartAt,aJSONOptions),
});
Classe de paramètre d'appel d'un web service objet X3 qui hérite de XTENDWSVC.classParam.
XTENDWSVC.classParamObject=Class.create(XTENDWSVC.classParam,{
/---------------------------------------
//aJSONOptions : Options JSON
//aTimeStampX3 : String - TimeStamp de l'objet X3 (peut être null ou vide)
//Ajoute le paramètre WW_MODSTAMP dans le groupe ADXTEC avec la valeur aTimeStamp
initialize: function(aTimeStampX3,aJSONOptions),
});
Classe qui représente les options JSON.
//---------------------------------------
//Active l'option noGroups
noGroups:function(),
//---------------------------------------
//Active l'option noRows
noRows:function(),
//---------------------------------------
//Active l'option noLabels
noLabels:function(),
//---------------------------------------
//Active l'option noClobs
noClobs:function(),
/---------------------------------------
//Met à jour la liste des groupes à exclure
//aValue : String or Array of string
excludeGrp:function(aValue),
//---------------------------------------
//Met à jour la liste des groupes à inclure
includeGrp:function(aValue),
//---------------------------------------
//Met à jour la liste des champs à exclure
excludeFld:function(aValue),
//---------------------------------------
//Met à jour la liste des champs à inclure
includeFld:function(aValue),
/*------------- EXEMPLE -------------*/
var wOpts=new XTENDWSVC.classJsonOpt().noGroups().includeFld(["SOHNUM""ITMREF","QTY"]);
Il s'agit de la classe de base utilisée pour appeler un web service REST.
Par défaut cette classe ne permet pas de poster plusieurs requête simultanément et bloque les tentative d'appels multiples.
/*---------------- METHODES PRINCIPALES ----------------*/
//Constructeur
//aInterfaceId : ID de l'interface XTEND
//Facultatif : on peut passer les fonctions CallBack statiques en paramètre
// si non implémentée dans la classe
// -> aInterfaceId,onSuccess,onFailure,onException
initialize:function(aInterfaceId),
//-------------------------------------------------------
//Vérifie si appel en cours et déclenche l'envoi de la requête
//aUrl : Url du service
//aData : Données
//aContenType : ContentType
exec:function(aUrl,aData ,aContenType),
/*-------- METHODE CALLBACK A SURCHARGER OBLIGATOIREMENT ----------*/
// HTTP STATUS=200
// !! La méthode filles doit appeler $super(response) pour positionner
// l'indicateur d'appel à false
onSuccess:function(response),
/*--------- METHODE CALLBACK A SURCHARGER EVENTUELLEMENT ----------*/
// EXCEPTION JAVASCRIPT
//Par défaut cette méthode affiche l'exception
// !! La méthode filles doit appeler $super(request,exception,true)
// pour positionner l'indicateur d'appel à false sans afficher le résultat
onException:function(request,exception,aIsOverriden),
//-------------------------------------------------------
// HTTP STATUS!=200
//Par défaut cette méthode affiche la cause de l'erreur
// !! La méthode filles doit appeler $super(request,headerJSON,true)
// pour positionner l'indicateur d'appel à false sans afficher le résultat
onFailure:function(response,headerJSON,aIsOverriden),
/*--------------------- FORMATS --------------------*/
//Fixe application/json comme type de données en retour
//Type par défaut
setReturnJSON:function(),
//-------------------------------------------------------
//Fixe application/xml comme type de données en retour
setReturnXML:function(),
//-------------------------------------------------------
//True si données XML en retour
returnXML:function(),
//-------------------------------------------------------
//True si données JSON en retour
returnJSON:function(),
/*--------------------- DIVERS ---------------------*/
//poste effectivement la requête vers le serveur si pas d'appel en cours
sendRequest:function(aUrl,aDataObject,aContenType)
//-------------------------------------------------------
//Renvoie l'id de l'interface
getId:function(),
/*------------- GESTION APPELS MULTIPLES -------------*/
//A surcharger si on veut débloquer les appels multiples
//aBusy : True si appel en cours
//Renvoie true pour autoriser l'appel du web service
doSendRequest:function(aBusy),
//-------------------------------------------------------
//Met à jour l'indicateur d'occupation
setBusy:function(aYes),
//-------------------------------------------------------
//True si appel en cours
isBusy:function(),
Il s'agit de la classe de base utilisée pour appeler un web service REST sous-programme.
XTENDWSVC.classCallerSpg=Class.create(XTENDWSVC.classCaller,{
//-------------------------------------------------------
//Constructeur
initialize:function(aInterfaceId),
//-------------------------------------------------------
//Exécute la requête avec les données aData
//Valeur autorisée pour aData
// -null ou undefined -> this.exec()
// -String -> this.exec(aString,'text/plain')
// -Hash -> this.runFORMENCODED(aData)
// -Autre -> this.runJSON(Object.toJSON(aData))
run:function(aData),
//-------------------------------------------------------
//Exécute la requête avec les données XML aXML
runXML:function(aXML),
//-------------------------------------------------------
//Exécute la requête avec les données JSON aJSON
// JSON : String JSON ou objet JavaScript (classe paramètre)
runJSON:function(aJSON),
//-------------------------------------------------------
//Exécute la requête avec le tableau de clés/valeurs aHash
//aHash représente le contenu d'un formulaire <form>
runFORMENCODED:function(aHash),
});
L'exemple ci-dessous appel l'interface XTDLOGIN du site courant et affiche la réponse.
Call Sous-Programme
var wClassCaller=Class.create(XTENDWSVC.classCallerSpg,{
//Constructeur facultatif si pas dautres paramètres que aInterfaceId
initialize:function($super,aInterfaceId){
$super(aInterfaceId);
},
//Méthode obligatoire pour traiter la réponse
onSuccess:function(response){
response.xtdDisplay();
}
});
var wJSONOpts=new XTENDWSVC.classJsonOpt().noGroups();
var wParams=new XTENDWSVC.classParamXtdSpg(wJSONOpts);
wParams.add("AXUSERCODE","DIS001");
wParams.add("AXPWD","adonix");
new wClassCaller("XTDLOGIN").run(wParams);
Résultat
URL :
http://ecfdalbopro:28980/xtend/ajax/SOLPAIE/PAIE/FDBTEST/INT/XTDLOGIN
Content-Type :
application/json;charset=utf-8
X3 INFORMATION MESSAGES :
Vous êtes bien connectés avec le code utilisateur DIS001
{
"AXUSERCODE":"DIS001",
"AXPWD":"adonix",
"AXUSERPROF":"B2B",
"AX3SOL":["SOLPAIE","X3V5","XTENDV2"],
"AX3FLDR":["PAIE","X3TESTV5","DEMOFRA"],
"AX3LANG":["FRA","FRA","FRA"],
"AX3USER":["XTEND","JPJ1","OG"],
"AX3PWD":["adonix","",""],
"AXLOGCOD":["NAME","FIRSTNAME","EMAIL","PHONE"],
"AXLOGVAL":["DAL BO","Frédéric","frdal@sage.com","00102030405"],
"SHIPADR1":["Sage Lyon new","Sage MGE","Sage PARIS"],
"SHIPCITY":["LYON","Echirolles","PARIS"],
"SHIPZIP":["69443","38130","75834"]
}
Il s'agit de la classe de base utilisée pour appeler un web service REST objet X3.
XTENDWSVC.classCallerObject=Class.create(XTENDWSVC.classCaller,{
//-------------------------------------------------------
//Constructeur
initialize:function(aInterfaceId),
//-------------------------------------------------------
//Méthode save
//aData : Données au format JSON ou XML
actCreate:function(aData),
//-------------------------------------------------------
//Méthode Read
//aHashKeys : Hash qui contient les clés de l'objet
actRead:function(aHashKeys),
//-------------------------------------------------------
//Méthode Delete
//aHashKeys : Hash qui contient les clés de l'objet
actDelete:function(aHashKeys),
//-------------------------------------------------------
//Méthode Modify
//aHashKeys : Hash qui contient les clés de l'objet
//aData : Données au format JSON ou XML
actUpdate:function(aHashKeys,aData),
//-------------------------------------------------------
//Action de code aCode
//aCode : Code de l'action
//aHashKeys : Hash qui contient les clés de l'objet
actOtherKey:function(aCode,aHashKeys),
//-------------------------------------------------------
//Action de code aCode
//aCode : Code de l'action
//aData : Données au format JSON ou XML
actOtherData:function(aCode,aData),
//-------------------------------------------------------
//Action query liste gauche
//aHashKeys : Hash qui contient les clés pour la sélection
//aReturnedCount : Optionnel - Nombre de lignes demandées
actQuery:function(aHashKeys,aReturnedCount),
});
L'exemple ci-dessous appel l'interface objet X3 OBJAYZ (objet AYZ) du site courant en création et affiche la réponse.
Call Objet
var wClassCaller=Class.create(XTENDWSVC.classCallerObject,{
onSuccess:function(response){
response.xtdDisplay();
}
});
var wJSONOpts=new XTENDWSVC.classJsonOpt().noGroups();
var wParams=new XTENDWSVC.classParamObject(null,wJSONOpts);
wParams.add("TTL","Titre du formulaire");
wParams.add("MAICOD","frdal@sage.com");
wParams.add("CMT","Commentaire");
new wClassCaller("OBJAYZ").actCreate(wParams);
Résultat
URL :
http://ecfdalbopro:28980/xtend/ajax/SOLPAIE/PAIE/FDBTEST/INT/OBJAYZ/S
Content-Type :
application/json;charset=utf-8
X3 INFORMATION MESSAGES :
Formulaire créé
{
"FRMCOD":"0902000005",
"FCYCOD":"FDBTEST",
"ZFCYCOD":"Site de test fdalbo",
"TYP":"OTH",
"ZTYP":"Divers",
"STATUT":"1",
"STATUT_LBL":"A traiter",
"TTL":"Titre du formulaire",
"MAICOD":"frdal@sage.com",
"CREDAT":"20090227",
"CREHEURE":"184431",
"CMT":"Commentaire",
"PARCOD":[],
"PARVAL":[],
"WW_MODSTAMP":"000000000000",
"WW_MODUSER":""
}
La librairie XtendAjaxScripts.js met à disposition du développeur un ensemble de classe pour faciliter l'appel des web services REST de type script serveur.
Le script qui s'exécute sur le serveur XTEND accède au contexte de la session via l'interface IXtdAjaxScriptContext.
Il s'agit de la classe de base utilisée pour appeler un web service script serveur.
Cette classe fonctionne suivant le même principe que les web services interface mais les paramètres qui sont passés au script serveur sont libres.
Ils sont lus via la fonction XTD_CTX.getHttpBody et le contenu est interprété par le script lui même.
De même, le format de la réponse renvoyée est libre.
C'est la fonction print qui écrit directement les données (String) dans un buffer qui sera renvoyé vers le client.
La fonction XTD_CTX.setHttpContenType permet de gérer le ContentType de la réponse.
Par exemple, le script peut renvoyer du HTML qui sera inséré dynamiquement dans la page .
/*---------------- METHODES PRINCIPALES ----------------*/
//Constructeur
//aScriptId : Chemin relatiif du scripts par rapport à la racine des scripts
//Facultatif : on peut passer les fonctions CallBack statiques en paramètre
// si non implémentée dans la classe
// -> aScriptId,onSuccess,onFailure,onException
initialize:function(aScriptId),
//-------------------------------------------------------
//Exécute les script avec aParams comme paramètre
//Le contenu de aParams est libre est dépend du script appelé
run:function(aParams),
/*-------- METHODE CALLBACK A SURCHARGER OBLIGATOIREMENT ----------*/
// HTTP STATUS=200
// !! La méthode filles doit appeler $super(response) pour positionner
// l'indicateur d'appel à false
onSuccess:function(response),
/*--------- METHODE CALLBACK A SURCHARGER EVENTUELLEMENT ----------*/
// EXCEPTION JAVASCRIPT
//Par défaut cette méthode affiche l'exception
// !! La méthode filles doit appeler $super(request,exception,true)
// pour positionner l'indicateur d'appel à false sans afficher le résultat
onException:function(request,exception,aIsOverriden),
//-------------------------------------------------------
// HTTP STATUS!=200
//Par défaut cette méthode affiche la cause de l'erreur
// !! La méthode filles doit appeler $super(request,headerJSON,true)
// pour positionner l'indicateur d'appel à false sans afficher le résultat
onFailure:function(response,headerJSON,aIsOverriden),
/*------------- GESTION APPELS MULTIPLES -------------*/
//A surcharger si on veut débloquer les appels multiples
//aBusy : True si appel en cours
//Renvoie true pour autoriser l'appel du web service
doSendRequest:function(aBusy),
//-------------------------------------------------------
//Met à jour l'indicateur d'occupation
setBusy:function(aYes),
//-------------------------------------------------------
//True si appel en cours
isBusy:function()
Cette classe permet de mettre à jour un élément du DOM HTML (div, span...) à réception de la réponse du web service si celui-ci renvoie une réponse HTML text/html.
XTENDSCRIPTS.classUpdater=Class.create(XTENDSCRIPTS.classCaller,{
//-------------------------------------------------------
//Constructeur
//aScriptId : Path du script serveur
//aUpdateId : ID de l'element du DOM à'mettre à jour
//aClearBefore : True pour effacer le contenu de aUpdateId avant envoi de la requête
initialize: function(aScriptId,aUpdateId,aClearBefore),
//-------------------------------------------------------
// Exécute le script avec aParams comme paramètre
run:function(aParams),
});
Appel d'un script qui lit 2 paramètre P1 et P2 et renvoie le contenu des paramètres sous forme d'un contenu HTML.
Script
//Include de la librairie utilitaires
#include "libs\xtdWsvc.js"
//Lecture des données envoyées par le client
// -> Dans cet exemple il s'agit de données JSON
// -> String au format : {P1:"ValeurP1",P2:"ValeurP2"}
//La fonction Eval crée un objet JavaScrit à partir de la String
var wInput=eval('('+XTD_CTX.getHttpBody()+')');
//Objet utilitaire pour construire la réponse HTML
var wHtml=new XTENDWSVC.classHTMLBuffer;
//On renvoie un HTML qui contient les paramètres écrits en gras
wHtml.append("<b>P1=").append(wInput.P1).append("</b><br>");
wHtml.append("<b>P2=").append(wInput.P2).append("</b><br>");
//Ecriture de la réponse
print(wHtml.html());
//Mise à jour du ContenType
XTD_CTX.setHttpContenType("text/html");
Appel à partir de la page HTML
<Script>
function callAjaxScript(aP1,aP2){
//Paramètres
var wParams={P1:aP1,P2:aP2};
//ajaxTest3.js est le path du scripts
//idReponseScript est l'id de la div qui affiche le résultat HTML
//true pour effacer le contenu de la div avant appel du script
new XTENDSCRIPTS.classUpdater("ajaxTest3.js","idReponseScript",true).run(wParams);
}
</script>
<!--Bouton pour déclencher l'appel-->
<input type="button" value="callAjaxScript" onClick="javascript:callAjaxScript('Hello','world');"><br>
<!--div pour afficher le résultat-->
<div id="idReponseScript"></div>
Résultat de la réquête