Les types de données SOAP et les types de données 1000
m (a renommé Developpement:WebService3 en Les types de données SOAP (ws)) |
|||
Ligne 1 : | Ligne 1 : | ||
{{#customtitle:Les types de données SOAP et les types de données 1000}} | {{#customtitle:Les types de données SOAP et les types de données 1000}} | ||
− | ==Les types de données SOAP et Ligne 1000== | + | ===Les types de données SOAP et Ligne 1000=== |
L’exemple précédent utilisait un service très simple échangeant une chaine de caractère, les types utilisables dans les WS peuvent être plus compliqués et s’appuient sur les types définis par les Schémas XML | L’exemple précédent utilisait un service très simple échangeant une chaine de caractère, les types utilisables dans les WS peuvent être plus compliqués et s’appuient sur les types définis par les Schémas XML | ||
− | ==Les principaux types simples == | + | ===Les principaux types simples === |
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
− | + | !SOAP | |
− | + | !Ligne 1000 | |
− | + | !Commentaire | |
|- | |- | ||
|string | |string | ||
Ligne 48 : | Ligne 48 : | ||
|Une chaine encodée contenant les données binaires | |Une chaine encodée contenant les données binaires | ||
|} | |} | ||
− | |||
− | |||
Les types SOAP sont reconnus comme des types de données natifs par 1000 | Les types SOAP sont reconnus comme des types de données natifs par 1000 | ||
− | ==Les types binaires== | + | ===Les types binaires=== |
− | + | ||
SOAP permet d’échanger des éléments binaires encodé soit en base 64 (base64Binary) soit en hexadécimal (hexBinary). | SOAP permet d’échanger des éléments binaires encodé soit en base 64 (base64Binary) soit en hexadécimal (hexBinary). | ||
Pour permettre de manipuler ces données binaires des propriétés base64Binary et hexBinary ont été ajouté au type de données binaires du Framework (TfwPicture, TfwBinary, TfwMemo), et de nouveaux objets techniques ont été introduis : | Pour permettre de manipuler ces données binaires des propriétés base64Binary et hexBinary ont été ajouté au type de données binaires du Framework (TfwPicture, TfwBinary, TfwMemo), et de nouveaux objets techniques ont été introduis : | ||
− | TBinaryContent | + | *[[Contenus binaires (tech)|TBinaryContent]] |
C’est un type générique permettant de contenir des données binaires. | C’est un type générique permettant de contenir des données binaires. | ||
Ligne 65 : | Ligne 62 : | ||
Exemple d’utilisation : | Exemple d’utilisation : | ||
− | < | + | <source lang='delphi'> |
// Procedure SendClaim; | // Procedure SendClaim; | ||
// | // | ||
Ligne 87 : | Ligne 84 : | ||
inst.sendClaim(body,content.base64Binary); | inst.sendClaim(body,content.base64Binary); | ||
end; | end; | ||
− | </ | + | </source> |
− | + | ||
Exemple : | Exemple : | ||
Ligne 96 : | Ligne 92 : | ||
Le service : | Le service : | ||
− | < | + | <source lang='delphi'> |
Type | Type | ||
InteropService = Class(TServiceLocal) | InteropService = Class(TServiceLocal) | ||
Ligne 106 : | Ligne 102 : | ||
output := input; | output := input; | ||
end; | end; | ||
− | </ | + | </source> |
Le proxy local du service : | Le proxy local du service : | ||
− | < | + | <source lang='delphi'> |
Type | Type | ||
ICinteropservice = Class(TServiceDistant) | ICinteropservice = Class(TServiceDistant) | ||
Ligne 121 : | Ligne 117 : | ||
//Remote procedure, do not code | //Remote procedure, do not code | ||
end; | end; | ||
− | </ | + | </source> |
L’appel du service en utilisant des chaînes de caractères : | L’appel du service en utilisant des chaînes de caractères : | ||
− | < | + | <source lang='delphi'> |
//Procedure echoBase64; | //Procedure echoBase64; | ||
var inst:ICinteropService; | var inst:ICinteropService; | ||
Ligne 157 : | Ligne 153 : | ||
else showMessage('echoBase64 OK'); | else showMessage('echoBase64 OK'); | ||
end; | end; | ||
− | </ | + | </source> |
L’appel du service en utilisant des TStringList | L’appel du service en utilisant des TStringList | ||
− | < | + | <source lang='delphi'> |
//Procedure echoBase64_2; | //Procedure echoBase64_2; | ||
var inst:ICinteropService; | var inst:ICinteropService; | ||
Ligne 177 : | Ligne 173 : | ||
lsout.SaveToFile('c:\myText-2.txt'); | lsout.SaveToFile('c:\myText-2.txt'); | ||
end; | end; | ||
− | </ | + | </source> |
Même exemple en utilisant une compression : | Même exemple en utilisant une compression : | ||
− | < | + | <source lang='delphi'> |
//Procedure echoBase64_3; | //Procedure echoBase64_3; | ||
var inst:ICinteropService; | var inst:ICinteropService; | ||
Ligne 197 : | Ligne 193 : | ||
lsout.SaveToFile('c:\myText-3.txt'); | lsout.SaveToFile('c:\myText-3.txt'); | ||
end; | end; | ||
− | </ | + | </source> |
− | + | ||
− | + | ||
+ | ===Les énumérés=== | ||
Le protocole SOAP permet de définir des énumérations de valeurs pour préciser les valeurs possibles d’un paramètre de message. | Le protocole SOAP permet de définir des énumérations de valeurs pour préciser les valeurs possibles d’un paramètre de message. | ||
Ligne 207 : | Ligne 202 : | ||
Par exemple pour définir un service effectuant l’écho d’un énuméré : | Par exemple pour définir un service effectuant l’écho d’un énuméré : | ||
− | < | + | <source lang='delphi'> |
//Défini un énuméré. | //Défini un énuméré. | ||
EchoNum = (cstEcho1, cstEcho2) ; | EchoNum = (cstEcho1, cstEcho2) ; | ||
Ligne 215 : | Ligne 210 : | ||
output := input; | output := input; | ||
end; | end; | ||
− | </ | + | </source> |
Pour appeler ce service, (le service a été importé en utilisant un préfixe de paquet IC) : | Pour appeler ce service, (le service a été importé en utilisant un préfixe de paquet IC) : | ||
− | < | + | <source lang='delphi'> |
ICEchoNum = (cstEcho1,cstEcho2) ; | ICEchoNum = (cstEcho1,cstEcho2) ; | ||
Ligne 233 : | Ligne 228 : | ||
else showMessage('echoEnum OK'); | else showMessage('echoEnum OK'); | ||
end; | end; | ||
− | </ | + | </source> |
Les valeurs énumérées sont transmises par leur constantes et non par leur index, l’appel précédent génère le message suivant : | Les valeurs énumérées sont transmises par leur constantes et non par leur index, l’appel précédent génère le message suivant : | ||
Ligne 248 : | Ligne 243 : | ||
</pre> | </pre> | ||
− | ==Les types complexes (structures)== | + | ===Les types complexes (structures)=== |
− | + | ||
Le protocole SOAP permet d’échanger des types complexes sous forme de structure. | Le protocole SOAP permet d’échanger des types complexes sous forme de structure. | ||
Ligne 256 : | Ligne 250 : | ||
Appel d’un service effectuant l’écho d’une structure : | Appel d’un service effectuant l’écho d’une structure : | ||
− | < | + | <source lang='delphi'> |
//Procedure echoStruct; | //Procedure echoStruct; | ||
// | // | ||
Ligne 275 : | Ligne 269 : | ||
showMessage('Result:'+structout.varString); | showMessage('Result:'+structout.varString); | ||
end; | end; | ||
− | </ | + | </source> |
− | + | ||
− | + | ||
+ | ===Les extensions de type complexe.=== | ||
Une extension de type complexe permet d’enrichir un type complexe préalablement défini, la correspondance en Ligne 1000 est une classe héritant de la classe enrichie. | Une extension de type complexe permet d’enrichir un type complexe préalablement défini, la correspondance en Ligne 1000 est une classe héritant de la classe enrichie. | ||
+ | {{info|Lors de la publication d’un service toutes les classes dérivées d’une classe publiée sont publiées.}} | ||
− | + | ===Les tableaux et références.=== | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | ==Les tableaux et références.== | + | |
− | + | ||
Le protocole SOAP permet d’échanger des ensembles de données sous forme de tableaux. L’implémentation de 1000 distingue les tableaux de type simple des tableaux de structure. | Le protocole SOAP permet d’échanger des ensembles de données sous forme de tableaux. L’implémentation de 1000 distingue les tableaux de type simple des tableaux de structure. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
− | + | !Scénarii | |
− | + | !Correspondance ligne 1000 | |
|- | |- | ||
− | | | + | |Tableau de type simple (t1) passé en paramètre |
|Tableau ouvert du type simple (t1) dans les paramètres de l’opération | |Tableau ouvert du type simple (t1) dans les paramètres de l’opération | ||
const p : Array of t1 ; | const p : Array of t1 ; | ||
|- | |- | ||
− | | | + | |Tableau de structure (s1) en paramètre |
|Liste d’objet de la classe représentant la structure (s1) dans les paramètres de l’opération | |Liste d’objet de la classe représentant la structure (s1) dans les paramètres de l’opération | ||
const p : s1List ; | const p : s1List ; | ||
|- | |- | ||
− | | | + | |Tableau de structure (s1) dans une structure (s2) |
|Rôle liste vers la structure (s1) du tableau dans la classe de la structure (s2) | |Rôle liste vers la structure (s1) du tableau dans la classe de la structure (s2) | ||
|- | |- | ||
− | | | + | |Type complexe (s1) référençant un type complexe (s2) |
|Rôle référence vers la structure (s1) dans la classe de la structure (s2) | |Rôle référence vers la structure (s1) dans la classe de la structure (s2) | ||
|- | |- | ||
− | | | + | |Tableau de type simple (t1) dans une structure (s2). |
|Rôle liste vers une classe wrapper du type simple (t1) dans la classe de la structure (s2) | |Rôle liste vers une classe wrapper du type simple (t1) dans la classe de la structure (s2) | ||
|} | |} | ||
− | === | + | ====Tableau de type simple passé en paramètre.==== |
− | + | ||
Exemple: | Exemple: | ||
− | < | + | <source lang='delphi'> |
Procedure echoArrayOfString(const input:Array of string; out output:Array of string); | Procedure echoArrayOfString(const input:Array of string; out output:Array of string); | ||
var idx:Integer; | var idx:Integer; | ||
Ligne 331 : | Ligne 317 : | ||
output[idx] := input[idx]; | output[idx] := input[idx]; | ||
End ; | End ; | ||
− | </ | + | </source> |
Pour appeler ce service : | Pour appeler ce service : | ||
− | < | + | <source lang='delphi'> |
Procedure echoArrayOfString ; | Procedure echoArrayOfString ; | ||
var inst:ICinteropService; sin,sout:Array of string; | var inst:ICinteropService; sin,sout:Array of string; | ||
Ligne 365 : | Ligne 351 : | ||
else showMessage('echoArrayString OK'); | else showMessage('echoArrayString OK'); | ||
end; | end; | ||
− | </ | + | </source> |
− | === | + | ====Tableau de type complexe passé en paramètre.==== |
Un type complexe étant une classe un tableau de type complexe est une liste d’objet de cette classe | Un type complexe étant une classe un tableau de type complexe est une liste d’objet de cette classe | ||
Ligne 373 : | Ligne 359 : | ||
Par exemple pour échanger une liste de SOAPStruct | Par exemple pour échanger une liste de SOAPStruct | ||
− | < | + | <source lang='delphi'> |
Type | Type | ||
InteropStruct1 = Class(TitObject) | InteropStruct1 = Class(TitObject) | ||
Ligne 401 : | Ligne 387 : | ||
Procedure echoStruct1Array(const input:InteropStruct1List; out output:InteropStruct1List); | Procedure echoStruct1Array(const input:InteropStruct1List; out output:InteropStruct1List); | ||
end; | end; | ||
− | </ | + | </source> |
Pour appeler ce service : | Pour appeler ce service : | ||
− | < | + | <source lang='delphi'> |
Procedure echoStructArray; | Procedure echoStructArray; | ||
var inst:ICinteropService; | var inst:ICinteropService; | ||
Ligne 474 : | Ligne 460 : | ||
showMessage('echoStruct1 OK'); | showMessage('echoStruct1 OK'); | ||
end; | end; | ||
− | </ | + | </source> |
− | === | + | ====Tableau de structure dans une structure.==== |
Un type complexe SOAP peut contenir des tableaux, 1000 modélise un tableau contenu dans un type complexe par un rôle liste composition. | Un type complexe SOAP peut contenir des tableaux, 1000 modélise un tableau contenu dans un type complexe par un rôle liste composition. | ||
Ligne 482 : | Ligne 468 : | ||
Voir l’exemple précédent. | Voir l’exemple précédent. | ||
− | === | + | ====Type complexe référençant un élément de type complexe.==== |
Un type complexe SOAP peut référencer un élément de type complexe, 1000 modélise l’élément comme une référence composition référençant le type complexe. | Un type complexe SOAP peut référencer un élément de type complexe, 1000 modélise l’élément comme une référence composition référençant le type complexe. | ||
− | === | + | ====Tableau de type simple dans une structure.==== |
La ligne 1000 ne permet pas de manipuler nativement des tableaux de type simple comme attribut de classes. Pour permettre l’échange de ces tableaux elle définit des classes Wrapper de types simples puis utilise des tableaux sur ces classes. | La ligne 1000 ne permet pas de manipuler nativement des tableaux de type simple comme attribut de classes. Pour permettre l’échange de ces tableaux elle définit des classes Wrapper de types simples puis utilise des tableaux sur ces classes. | ||
Ligne 496 : | Ligne 482 : | ||
{{#images:image20.png|Web_Services_1000}} | {{#images:image20.png|Web_Services_1000}} | ||
− | < | + | <source lang='delphi'> |
unit InterpServicePackage | unit InterpServicePackage | ||
interface | interface | ||
Ligne 527 : | Ligne 513 : | ||
end. | end. | ||
− | </ | + | </source> |
Lorsque ce service est publié en WSDL, la classe wrapper n’apparait pas et un élément de type tableau est publié : | Lorsque ce service est publié en WSDL, la classe wrapper n’apparait pas et un élément de type tableau est publié : | ||
Ligne 579 : | Ligne 565 : | ||
L’appel de la fonction echStruct5 avec le passage des éléments du tableau : | L’appel de la fonction echStruct5 avec le passage des éléments du tableau : | ||
− | < | + | <source lang='delphi'> |
Procedure TestInteropService.echoStruct5; | Procedure TestInteropService.echoStruct5; | ||
var inst:ICinteropService; | var inst:ICinteropService; | ||
Ligne 606 : | Ligne 592 : | ||
showMessage('echoStruct5 :'+ss); | showMessage('echoStruct5 :'+ss); | ||
end; | end; | ||
− | </ | + | </source> |
Ce qui génère le message suivant : | Ce qui génère le message suivant : | ||
Ligne 625 : | Ligne 611 : | ||
</pre> | </pre> | ||
− | ==Publication des rôles des classes utilisées comme type complexe soap.== | + | ===Publication des rôles des classes utilisées comme type complexe soap.=== |
− | + | ||
Lorsqu’ une classe, utilisée dans un service, est publiée dans un descriptif de service (WSDL) elle y inclut tous les rôles référençant une classe du paquet de service. Un rôle référençant une classe à l’extérieur du paquet de service ne sera pas publié. | Lorsqu’ une classe, utilisée dans un service, est publiée dans un descriptif de service (WSDL) elle y inclut tous les rôles référençant une classe du paquet de service. Un rôle référençant une classe à l’extérieur du paquet de service ne sera pas publié. | ||
− | + | {{Footer|Web Services (ws)}} | |
− | + | [[Category:Web Services]] | |
− | + | ||
− | + | ||
− | + | ||
− | { | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | {| | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | [[Category: | + |
Version actuelle en date du 22 août 2009 à 09:40
Sommaire |
Les types de données SOAP et Ligne 1000
L’exemple précédent utilisait un service très simple échangeant une chaine de caractère, les types utilisables dans les WS peuvent être plus compliqués et s’appuient sur les types définis par les Schémas XML
Les principaux types simples
SOAP | Ligne 1000 | Commentaire |
---|---|---|
string | String | |
int | Integer | |
decimal | Currency | Le type Decimal peut comporter jusqu’à 128 décimales, la ligne 1000 ne permet que 4 décimales |
float, double | Double | |
dateTime | TDateTime | |
date | Date | |
time | Time | |
boolean | Boolean | |
base64Binary | String | Une chaine encodée contenant les données binaires |
Les types SOAP sont reconnus comme des types de données natifs par 1000
Les types binaires
SOAP permet d’échanger des éléments binaires encodé soit en base 64 (base64Binary) soit en hexadécimal (hexBinary).
Pour permettre de manipuler ces données binaires des propriétés base64Binary et hexBinary ont été ajouté au type de données binaires du Framework (TfwPicture, TfwBinary, TfwMemo), et de nouveaux objets techniques ont été introduis :
C’est un type générique permettant de contenir des données binaires.
Exemple d’utilisation :
// Procedure SendClaim; // var inst:TACwsiattachement; body:TACClaimDetailType; content: TBinaryContent; begin // Objet gestionnaire de binaire content := TBinaryContent.Create; // Chargement de l’objet avec une image content.LoadFromFile('d:\Mes documents\Mes images\white house.jpg'); // Descriptif de l’image attendu par le service body := ClassManager.CreateInstance('TACClaimDetailType'); body.Name := 'White house'; // inst := ClassManager.CreateInstance('TACwsiattachement'); inst.sendClaim(body,content.base64Binary); end;
Exemple :
Cet exemple montre comment appelé un service exécutant l’écho d’un paramètre binaire :
Le service :
Type InteropService = Class(TServiceLocal) Procedure echoBase64(const input:base64Binary; out output:base64Binary); end; Procedure InteropService.echoBase64(const input:base64Binary; out output:base64Binary); begin output := input; end;
Le proxy local du service :
Type ICinteropservice = Class(TServiceDistant) public Procedure echoBase64(const input:base64Binary; out output:base64Binary); end; Procedure ICinteropservice.echoBase64(const input:base64Binary; out output:base64Binary); begin //Remote procedure, do not code end;
L’appel du service en utilisant des chaînes de caractères :
//Procedure echoBase64; var inst:ICinteropService; sin:string; sout:base64binary; contin,contout:TBinaryContent; begin inst := ClassManager.CreateInstance('ICinteropService'); // Une chaine a transmettre sin := 'coucou'; // Converti la chaine en utilisant un BinaryContent // contin := TBinaryContent.Create; contin.AsString := sin; // appel du service // sout contient la réponse encodée inst.echoBase64(contin.base64Binary,sout); // converti la réponse // contout := TBinaryContent.Create; contout.base64Binary := sout; // compare le résultat // if sin<>contout.AsString then showMessage('echoBase64 failed') else showMessage('echoBase64 OK'); end;
L’appel du service en utilisant des TStringList
//Procedure echoBase64_2; var inst:ICinteropService; lsin,lsout:TStringList; sout: base64binary; begin inst := ClassManager.CreateInstance('ICinteropService'); lsin := TStringList.Create; lsin.LoadFromFile('c:\myText-1.txt'); inst.echoBase64(lsin.base64binary,sout); lsout := TStringlist.Create; lsout.base64Binary := sout; lsout.SaveToFile('c:\myText-2.txt'); end;
Même exemple en utilisant une compression :
//Procedure echoBase64_3; var inst:ICinteropService; lsin,lsout:TStringList; sout: base64Binary; begin inst := ClassManager.CreateInstance('ICinteropService'); lsin := TStringList.Create; lsin.LoadFromFile('c:\myText-1.txt'); inst.echoBase64(lsin.getAsBase64Binary(b64ZlibNoSig),sout); lsout := TStringlist.Create; lsout.setAsBase64Binary(sout,b64ZLibNoSig); lsout.SaveToFile('c:\myText-3.txt'); end;
Les énumérés
Le protocole SOAP permet de définir des énumérations de valeurs pour préciser les valeurs possibles d’un paramètre de message.
Un énuméré SOAP correspond à un énuméré Ligne 1000.
Par exemple pour définir un service effectuant l’écho d’un énuméré :
//Défini un énuméré. EchoNum = (cstEcho1, cstEcho2) ; //Procedure echoEnum(input:EchoEnum; out output:EchoEnum); begin output := input; end;
Pour appeler ce service, (le service a été importé en utilisant un préfixe de paquet IC) :
ICEchoNum = (cstEcho1,cstEcho2) ; // Procedure echoEnum; // var inst:ICinteropService; sin,sout:ICEchoEnum; begin sin := cstEcho1; inst := ClassManager.CreateInstance('ICinteropService'); inst.echoEnum(cstEcho1,sout); if sin<>sout then showMessage('echoEnum failed') else showMessage('echoEnum OK'); end;
Les valeurs énumérées sont transmises par leur constantes et non par leur index, l’appel précédent génère le message suivant :
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <echoEnum xmlns="http://www.sage.com/fr/line1000/InterpServicePackage"> <input>cstEcho1</input> </echoEnum> </soap:Body> </soap:Envelope>
Les types complexes (structures)
Le protocole SOAP permet d’échanger des types complexes sous forme de structure.
Une structure SOAP correspond à une classe Ligne 1000.
Appel d’un service effectuant l’écho d’une structure :
//Procedure echoStruct; // var inst:DSService; structin,structout:DSSOAPStruct; begin // La structure est une classe 1000 structin := ClassManager.CreateInstance('DSSOAPStruct'); structin.varString := 'coucou'; structin.varInt := 1; structin.varFloat := 1.0; // appel du service inst := ClassManager.CreateInstance('DSService'); // l’instance en retour est créée par le framework inst.echoStruct(structin,structout); showMessage('Result:'+structout.varString); end;
Les extensions de type complexe.
Une extension de type complexe permet d’enrichir un type complexe préalablement défini, la correspondance en Ligne 1000 est une classe héritant de la classe enrichie.
Note : Lors de la publication d’un service toutes les classes dérivées d’une classe publiée sont publiées. |
Les tableaux et références.
Le protocole SOAP permet d’échanger des ensembles de données sous forme de tableaux. L’implémentation de 1000 distingue les tableaux de type simple des tableaux de structure.
Scénarii | Correspondance ligne 1000 |
---|---|
Tableau de type simple (t1) passé en paramètre | Tableau ouvert du type simple (t1) dans les paramètres de l’opération
const p : Array of t1 ; |
Tableau de structure (s1) en paramètre | Liste d’objet de la classe représentant la structure (s1) dans les paramètres de l’opération
const p : s1List ; |
Tableau de structure (s1) dans une structure (s2) | Rôle liste vers la structure (s1) du tableau dans la classe de la structure (s2) |
Type complexe (s1) référençant un type complexe (s2) | Rôle référence vers la structure (s1) dans la classe de la structure (s2) |
Tableau de type simple (t1) dans une structure (s2). | Rôle liste vers une classe wrapper du type simple (t1) dans la classe de la structure (s2) |
Tableau de type simple passé en paramètre.
Exemple:
Procedure echoArrayOfString(const input:Array of string; out output:Array of string); var idx:Integer; begin // Implémentation du service // Copie le tableau élément par élément. // for idx:=0 to length(input)-1 do output[idx] := input[idx]; End ;
Pour appeler ce service :
Procedure echoArrayOfString ; var inst:ICinteropService; sin,sout:Array of string; idx:Integer; s1,s2:string; begin inst := ICinteropService.Create; // Initialise le tableau par une constante sin := ['Ah','que','coucou']; // Appel du service, sout sera initialisée // par la couche soap inst.echoArrayOfString(sin,sout); // Verification // s1 := ''; for idx:=0 to length(sin)-1 do s1 := s1+sin[idx]; s2 := ''; for idx:=0 to length(sout)-1 do s2 := s2+sout[idx]; if s1<>s2 then showMessage('echoArrayString failed :'+s1+':'+s2) else showMessage('echoArrayString OK'); end;
Tableau de type complexe passé en paramètre.
Un type complexe étant une classe un tableau de type complexe est une liste d’objet de cette classe
Par exemple pour échanger une liste de SOAPStruct
Type InteropStruct1 = Class(TitObject) public InteropStruct2List: CompositionList of InteropStruct2; InteropStruct2Ref: InteropStruct2; InteropStruct3Ref: InteropStruct3; oidInteropStruct2Ref: string; oidInteropStruct3Ref: string; unCode1: string; end; InteropStruct2 = Class(TitObject) public InteropStruct1Ref: InteropStruct1; oidInteropStruct1Ref: string; unCode2: string; end; InteropStruct3 = Class(TitObject) public unCode3: string; end; InteropService = Class(Service) public Procedure echoStruct1Array(const input:InteropStruct1List; out output:InteropStruct1List); end;
Pour appeler ce service :
Procedure echoStructArray; var inst:ICinteropService; sin,sout:ICInteropStruct1List; s1i,s1o:ICInteropStruct1; idx:Integer; s2:ICInteropStruct2; begin inst := ICinteropService.Create; // Force l’appel distant inst.LoopMode := mlmNone; // Création de la liste d’appel. // sin := ClassManager.CreateObjectList('ICInteropStruct1'); // s1i := ICInteropStruct1.Create; s1i.unCode1 := 'code1'; for idx:=0 to 1 do begin s2 := ICInteropStruct2.Create; s2.unCode2 := 'code1-'+inttostr(idx); s1i.InteropStruct2List.AddRef(s2); end; sin.AddRef(s1i); // Appel du service // la liste sout sera initialisée // par la couche soap inst.echoStruct1Array(sin,sout); // Vérification // if sin.Count<>sout.Count then begin showMessage('echoStruct1Array failed, struct count'); Exit; end; // Test du premier élément s1i := sin.Refs[0]; s1o := sout.Refs[0]; if s1i.unCode1<>s1o.unCode1 then begin showMessage('echoStruct1Array failed, struc1.unCode1'); Exit; end; // // if s1i.InteropStruct2List.Count<>s1o.InteropStruct2List.Count then begin showMessage('echoStruct1Array failed, struc1.struct2.count'); Exit; end; // Test de la liste imbriquée // for idx:=0 to s1i.InteropStruct2List.Count-1 do if (s1i.InteropStruct2List.Refs[idx].unCode2<>s1o.InteropStruct2List.Refs[idx].unCode2) then begin showMessage('echoStruct1Array failed, struc1.struct2[].unCode2'); Exit; end; showMessage('echoStruct1 OK'); end;
Tableau de structure dans une structure.
Un type complexe SOAP peut contenir des tableaux, 1000 modélise un tableau contenu dans un type complexe par un rôle liste composition.
Voir l’exemple précédent.
Type complexe référençant un élément de type complexe.
Un type complexe SOAP peut référencer un élément de type complexe, 1000 modélise l’élément comme une référence composition référençant le type complexe.
Tableau de type simple dans une structure.
La ligne 1000 ne permet pas de manipuler nativement des tableaux de type simple comme attribut de classes. Pour permettre l’échange de ces tableaux elle définit des classes Wrapper de types simples puis utilise des tableaux sur ces classes.
Exemple :
Déclaration du service :
unit InterpServicePackage interface Type InteropService = Class(TitObject) public Procedure echoStruct5(const input:InteropStruct5; out output:InteropStruct5); end; InteropStringWrapper = Class(TitObject) // cette classe a l’option Wrapper de type simple coché dans ses propriétés soap public data : string; // les classes wrapper doivent avoir un attribut data end; Interopstruct5 = Class(TitObject) public unArrayOfString: List of InteropStringWrapper; unCode: string; end; Implementation {InteropService} Procedure InteropService.echoStruct5(const input:InteropStruct5; out output:InteropStruct5); begin output := input; end; end.
Lorsque ce service est publié en WSDL, la classe wrapper n’apparait pas et un élément de type tableau est publié :
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.sage.com/fr/line1000/InterpServicePackage" xmlns:tns="http://www.sage.com/fr/line1000/InterpServicePackage"> <wsdl:types> <xsd:schema elementFormDefault="qualified" targetNamespace="http://www.sage.com/fr/line1000/InterpServicePackage" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="echoStruct5"> <complexType> <sequence> <element name="input" type="tns:Interopstruct5" minOccurs="0" maxOccurs="1"/> </sequence> </complexType> </element> <complexType name="Interopstruct5"> <sequence> <element name="unArrayOfString" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/> <element name="unCode" type="xsd:string"/> </sequence> </complexType> <element name="echoStruct5Response"> <complexType> <sequence> <element name="output" type="tns:Interopstruct5" minOccurs="0" maxOccurs="1"/> </sequence> </complexType> </element> </xsd:schema> </wsdl:types> <wsdl:message name="echoStruct5"> <wsdl:part name="parameters" element="tns:echoStruct5"/> </wsdl:message> <wsdl:message name="echoStruct5Response"> <wsdl:part name="parameters" element="tns:echoStruct5Response"/> </wsdl:message> <wsdl:portType name="interopservicePortType"> <wsdl:operation name="echoStruct5"> <wsdl:input message="tns:echoStruct5" name="echoStruct5"/> <wsdl:output message="tns:echoStruct5Response" name="echoStruct5Respond"/> </wsdl:operation> </wsdl:portType>
L’import du wsdl de ce service génère le modèle suivant :
L’élément unArrayOfString, tableau de type simple, génère une classe wrapper et une référence liste sur cette classe.
L’appel de la fonction echStruct5 avec le passage des éléments du tableau :
Procedure TestInteropService.echoStruct5; var inst:ICinteropService; sin,sout:ICInteropStruct5; wrp:ICWrapperOfString; idx:Integer; ss,stag: string; begin inst := ICinteropService.Create; sin := ICInteropStruct5.Create; sin.unCode := 'code5'; for idx:=0 to 1 do begin wrp := ICWrapperOfString.Create; wrp.data := 'data-'+inttostr(idx); sin.unArrayOfString.AddRef(wrp); end; inst.echoStruct5(sin,sout); ss := ''; stag := #13; for idx:=0 to sout.unArrayOfString.Count-1 do begin ss := ss+stag+sout.unArrayOfString.refs[idx].data; end; showMessage('echoStruct5 :'+ss); end;
Ce qui génère le message suivant :
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <echoStruct5 xmlns="http://www.sage.com/fr/line1000/InterpServicePackage"> <input> <unArrayOfString>data-0</unArrayOfString> <unArrayOfString>data-1</unArrayOfString> <unCode>code5</unCode> </input> </echoStruct5> </soap:Body> </soap:Envelope>
Publication des rôles des classes utilisées comme type complexe soap.
Lorsqu’ une classe, utilisée dans un service, est publiée dans un descriptif de service (WSDL) elle y inclut tous les rôles référençant une classe du paquet de service. Un rôle référençant une classe à l’extérieur du paquet de service ne sera pas publié.