Web Service RPGLE Probleme CCSID
-
- Messages : 26
- Enregistré le : ven. 26 oct. 2018, 09:58:31
Web Service RPGLE Probleme CCSID
Bonjour,
Nous avons 2 partitions IBM i (V7R2 TR8 SF99720 niveau 18032)
Installés : 5770SS1 option 39, JV1 opt 11,14 à 17
variable environnement JAVA_HOME = .../JavaVM/jdk80/32bit
Mon soucis :
J'ai mis en place un web service REST en RPPGLEsur une partition "A" qui me renvoie des caractères accentués.
La réponse s'affiche correctement quand j'appelle le web service via un navigateur (mozilla,...), mais pas via une émulation 5250 à partir de ma partition B
PARTITION A (qui héberge le web service) :
- sysval QCCSID = 297
- Programme RPGLE
- renvoi du JSON
PARTITION B :
- sysval QCCSID = 65535, mais profil avec ccsid 297
- Appel du WebService via un SQLRPGLE ou via STRSQL
SELECT cast(substr(Reponse, 1, 1000) as varchar(1000))
FROM
(VALUES(SYSTOOLS.HTTPGETCLOB(
'http://[MonSysteme]/web/services/MonInfo/123456', ''))) ws(Reponse)
RENVOI : {"CODERETOUR":"Non Trouvé", ....}
====> probleme de conversion de CCSID quelque part, mais ou ?
idem si je met dans mon header :
'<header name="Content-Type" value="application/json;charset=UTF_8"/>'
Si j'appelle un web service sur internet qui renvoie des caractères accentué à partir de ma partition B ceux ci s'affichent correctement.
Je pense qu'il pourrait s'agir de la mise en place du web service et d'une config du serveur APACHE (V2.6) ou du web service
J'ai essayé à plusieurs endroit de mettre CCSID= UTF8, FR, 297, ... mais rien ne change malgré restart du serveur web.
Nous avons 2 partitions IBM i (V7R2 TR8 SF99720 niveau 18032)
Installés : 5770SS1 option 39, JV1 opt 11,14 à 17
variable environnement JAVA_HOME = .../JavaVM/jdk80/32bit
Mon soucis :
J'ai mis en place un web service REST en RPPGLEsur une partition "A" qui me renvoie des caractères accentués.
La réponse s'affiche correctement quand j'appelle le web service via un navigateur (mozilla,...), mais pas via une émulation 5250 à partir de ma partition B
PARTITION A (qui héberge le web service) :
- sysval QCCSID = 297
- Programme RPGLE
- renvoi du JSON
PARTITION B :
- sysval QCCSID = 65535, mais profil avec ccsid 297
- Appel du WebService via un SQLRPGLE ou via STRSQL
SELECT cast(substr(Reponse, 1, 1000) as varchar(1000))
FROM
(VALUES(SYSTOOLS.HTTPGETCLOB(
'http://[MonSysteme]/web/services/MonInfo/123456', ''))) ws(Reponse)
RENVOI : {"CODERETOUR":"Non Trouvé", ....}
====> probleme de conversion de CCSID quelque part, mais ou ?
idem si je met dans mon header :
'<header name="Content-Type" value="application/json;charset=UTF_8"/>'
Si j'appelle un web service sur internet qui renvoie des caractères accentué à partir de ma partition B ceux ci s'affichent correctement.
Je pense qu'il pourrait s'agir de la mise en place du web service et d'une config du serveur APACHE (V2.6) ou du web service
J'ai essayé à plusieurs endroit de mettre CCSID= UTF8, FR, 297, ... mais rien ne change malgré restart du serveur web.
Merci pour votre aide.
JYSA
JYSA
-
- Site Admin
- Messages : 813
- Enregistré le : mer. 14 févr. 2007, 18:00:03
- Localisation : Nantes
- Contact :
CCSID
Pour y voir plus clair, que donne cette requête avec un site publique ?
values
cast(
systools.httpgetclob(
'http://data.nantes.fr/api/publication/2 ... ormat=json', '')
as varchar(20000)
)
pour nous
values
cast(
systools.httpgetclob(
'http://data.nantes.fr/api/publication/2 ... ormat=json', '')
as varchar(20000)
)
pour nous
le "è" de collège est-il correct ?{"version":"1","nb_results":569,"data":[{ "geo" : { "name" : "Collège Anne de Bretagne"} ...
Christian Massé (Volubis.fr)
-
- Messages : 26
- Enregistré le : ven. 26 oct. 2018, 09:58:31
Bonjour,
Oui, les caractères accentués sont bien affichés quand je lance cette requête sur le site public.
=>
...."Collège Anne de Bretagne"} , "_l" : [ 47.2065481346042.....
Voila mon source WS en RPG (très simplifié pour ne tenir compte que des accents) :
Ctl-opt alwnull(*usrctl) pgminfo(*pcml:*module);
Ctl-opt dftactgrp(*no);
// par défaut : global server setting = 00819
Dcl-pi *n;
Reference Char(20);
Code1 Char(20) ccsid(297);
Code2 Char(20) ccsid(1208);
end-pi;
Code1 = 'éèçàùâêîôûäËïöü';
Code2 = 'éèçàùâêîôûäËïöü';
*inlr=*on;
Puis l'affichage qd j'appelle ce WS a parrtir d'une autre partition
sELECT cast(substr(Reponse, 1, 500) as varchar(500))
FROM
(VALUES(SYSTOOLS.HTTPGETCLOB(
'http://MonServeur:10032/web/services/WS1208/a',
''))) ws(Reponse)
=>
Fonction CAST
{"CODE1":"éèçà ùâêîôûÀà ïöü","CODE2":"éèçà ùâêîôû"}
Par contre, si j'appelle ce WS via mozilla (ou IE) la réponse est correcte :
{"CODE1":"éèçàùâêîôûäËïöü","CODE2":"éèçàùâêîôû"}
(tronqué sur char(20) mais c'est normal, c'est juste pour du test)
Oui, les caractères accentués sont bien affichés quand je lance cette requête sur le site public.
=>
...."Collège Anne de Bretagne"} , "_l" : [ 47.2065481346042.....
Voila mon source WS en RPG (très simplifié pour ne tenir compte que des accents) :
Ctl-opt alwnull(*usrctl) pgminfo(*pcml:*module);
Ctl-opt dftactgrp(*no);
// par défaut : global server setting = 00819
Dcl-pi *n;
Reference Char(20);
Code1 Char(20) ccsid(297);
Code2 Char(20) ccsid(1208);
end-pi;
Code1 = 'éèçàùâêîôûäËïöü';
Code2 = 'éèçàùâêîôûäËïöü';
*inlr=*on;
Puis l'affichage qd j'appelle ce WS a parrtir d'une autre partition
sELECT cast(substr(Reponse, 1, 500) as varchar(500))
FROM
(VALUES(SYSTOOLS.HTTPGETCLOB(
'http://MonServeur:10032/web/services/WS1208/a',
''))) ws(Reponse)
=>
Fonction CAST
{"CODE1":"éèçà ùâêîôûÀà ïöü","CODE2":"éèçà ùâêîôû"}
Par contre, si j'appelle ce WS via mozilla (ou IE) la réponse est correcte :
{"CODE1":"éèçàùâêîôûäËïöü","CODE2":"éèçàùâêîôû"}
(tronqué sur char(20) mais c'est normal, c'est juste pour du test)
Merci pour votre aide.
JYSA
JYSA
-
- Site Admin
- Messages : 813
- Enregistré le : mer. 14 févr. 2007, 18:00:03
- Localisation : Nantes
- Contact :
CCSID
j'ai copié votre code et je rencontre le même problème.
Web service appelé depuis un navigateur : OK,
depuis le gestionnaire de scripts SQL (ou 5250)-> prb.
j'ai enlevé les CCSID sur les définitions de zone, ca ne sert à rien, de toutes façons je serveur de web services transporte de l'UNICODE.
J'ai essayé ce code
toujours le même problème dans retour_data
puis j'ai essayé
enfin
toujours pas...le fichier est déclaré CCSID=1208, mais les caractères ne sont pas bon. je pense que c'est au niveau de httpgetclob que ca se passe.
Web service appelé depuis un navigateur : OK,
depuis le gestionnaire de scripts SQL (ou 5250)-> prb.
j'ai enlevé les CCSID sur les définitions de zone, ca ne sert à rien, de toutes façons je serveur de web services transporte de l'UNICODE.
J'ai essayé ce code
Code : Tout sélectionner
**free
dcl-s retour SQLTYPE(CLOB : 200);
exec sql
values (systools.httpgetClob('http://as400:10052/web/services/TESTCCSID/abc', ''))
into :retour;
dsply (%subst(retour_data : 1 : 50));
*INLR = *ON;
puis j'ai essayé
Code : Tout sélectionner
create table retourT (retour clob CCSID 1208)
et
insert into retourT values(
systools.httpgetClob(
'http://as400:10052/web/services/TESTCCSID/abc', '')
)
Code : Tout sélectionner
**free
dcl-s retour SQLTYPE(DBCLOB_file);
retour_name = '/temp/retour.json';
retour_nl = %len(%trim(retour_name));
retour_fo = SQFOVR;
exec sql
values (systools.httpgetClob('http://as400:10052/web/services/TESTCCSID/abc', ''))
into :retour;
*INLR = *ON;
Christian Massé (Volubis.fr)
-
- Messages : 26
- Enregistré le : ven. 26 oct. 2018, 09:58:31
Bonjour,
Quand on exporte les données via le DBCLOB_FILE, on dirait qu'il y a un double encodage ... je m'explique :
1) le caractère "é" est normalement codé en UTF8 sur 2 octets qui ont pour valeur héxa 0xC3 0xA9 et représentés par les codes EBCDIC 297 par "é".
2) les caractères "é" sont respectivement codés en UTF8 : 0xC3 0x83 et 0xC2 0xA9
Et nous retrouvons ces 4 codes dans le fichier IFS à la place du "é"
(visible avec un éditeur de texte en hexa sous Windows)
Pour contourner le problème, j'ai trouvé une solution à la "barbare" qui ne fonctionne que quand la réponse du WS n'excède pas 32000 OCTETS (sachant que les caractères accentués et autres sont codés sur 2 ou 3 octets en UTF8)
1) Créer une table FIC297 avec 1 zone char ccsid 297
2) Ecrire la réponse du WS dans la table
insert into FIC297 (Zone297)
(SELECT cast(substr(Reponse, 1, 32000) as Varchar(32000))
FROM (VALUES(SYSTOOLS.HTTPGETCLOB(
'http://as400:10032/web/services/AWS1208/a','')))
ws(Reponse))
3) Export de la table vers IFS:
CPYTOIMPF FROMFILE(FIC297)
TOSTMF('/TEMP/FicIfs.txt')
MBROPT(*REPLACE)
STMFCCSID(*PCASCII)
RCDDLM(*CRLF)
STRDLM(*NONE)
=> le fichier est créé avec CCSID 1252 par défaut
4) CHGATR OBJ('/TEMP/FicIfs.txt') ATR(*CCSID) VALUE(1208)
pour forcer la lecture suivante en UTF8
5) import dans une 2eme table FIC297B
CPYFRMIMPF FROMSTMF('/TEMP/FicIfs.txt')
TOFILE(FIC297B)
MBROPT(*REPLACE)
FROMCCSID(*FILE)
TOCCSID(*FILE)
RCDDLM(*CRLF)
STRDLM(*NONE)
FLDDLM(*TAB)
Et là le résultat est lisible.
Mais :
- je ne sais pas si ça fonctionne pour TOUS les caractères provenant de l'UTF8
- ça ne fonctionne QUE si la longueur de la réponse du web service n'excède pas 32000 OCTETS (puisque le codage en UTF8 peut se faire sur 2 ou 3 octets), soit
Il est possible de dépasser les 32000 octets mais il faudrait mettre en place une usine à gaz qui balaye la réponse du WS par tranche de 32000 octets ...
Ce que je n'arrive pas à comprendre c'est pourquoi ça ne fonctionne pas en local, alors que les caractères accentués sont affichés correctement quand on appelle un WS public (comme celui de Nantes que vous avez donné comme exemple )
Quand on exporte les données via le DBCLOB_FILE, on dirait qu'il y a un double encodage ... je m'explique :
1) le caractère "é" est normalement codé en UTF8 sur 2 octets qui ont pour valeur héxa 0xC3 0xA9 et représentés par les codes EBCDIC 297 par "é".
2) les caractères "é" sont respectivement codés en UTF8 : 0xC3 0x83 et 0xC2 0xA9
Et nous retrouvons ces 4 codes dans le fichier IFS à la place du "é"
(visible avec un éditeur de texte en hexa sous Windows)
Pour contourner le problème, j'ai trouvé une solution à la "barbare" qui ne fonctionne que quand la réponse du WS n'excède pas 32000 OCTETS (sachant que les caractères accentués et autres sont codés sur 2 ou 3 octets en UTF8)
1) Créer une table FIC297 avec 1 zone char ccsid 297
2) Ecrire la réponse du WS dans la table
insert into FIC297 (Zone297)
(SELECT cast(substr(Reponse, 1, 32000) as Varchar(32000))
FROM (VALUES(SYSTOOLS.HTTPGETCLOB(
'http://as400:10032/web/services/AWS1208/a','')))
ws(Reponse))
3) Export de la table vers IFS:
CPYTOIMPF FROMFILE(FIC297)
TOSTMF('/TEMP/FicIfs.txt')
MBROPT(*REPLACE)
STMFCCSID(*PCASCII)
RCDDLM(*CRLF)
STRDLM(*NONE)
=> le fichier est créé avec CCSID 1252 par défaut
4) CHGATR OBJ('/TEMP/FicIfs.txt') ATR(*CCSID) VALUE(1208)
pour forcer la lecture suivante en UTF8
5) import dans une 2eme table FIC297B
CPYFRMIMPF FROMSTMF('/TEMP/FicIfs.txt')
TOFILE(FIC297B)
MBROPT(*REPLACE)
FROMCCSID(*FILE)
TOCCSID(*FILE)
RCDDLM(*CRLF)
STRDLM(*NONE)
FLDDLM(*TAB)
Et là le résultat est lisible.
Mais :
- je ne sais pas si ça fonctionne pour TOUS les caractères provenant de l'UTF8
- ça ne fonctionne QUE si la longueur de la réponse du web service n'excède pas 32000 OCTETS (puisque le codage en UTF8 peut se faire sur 2 ou 3 octets), soit
Il est possible de dépasser les 32000 octets mais il faudrait mettre en place une usine à gaz qui balaye la réponse du WS par tranche de 32000 octets ...
Ce que je n'arrive pas à comprendre c'est pourquoi ça ne fonctionne pas en local, alors que les caractères accentués sont affichés correctement quand on appelle un WS public (comme celui de Nantes que vous avez donné comme exemple )
Merci pour votre aide.
JYSA
JYSA
-
- Site Admin
- Messages : 813
- Enregistré le : mer. 14 févr. 2007, 18:00:03
- Localisation : Nantes
- Contact :
Point service
je pense que ça vaut le coup d'ouvrir un incident au point service.
je m'y colle ! (mais ça risque d'être long)
je m'y colle ! (mais ça risque d'être long)
Christian Massé (Volubis.fr)
-
- Messages : 26
- Enregistré le : ven. 26 oct. 2018, 09:58:31
-
- Site Admin
- Messages : 813
- Enregistré le : mer. 14 févr. 2007, 18:00:03
- Localisation : Nantes
- Contact :
HTTPGETCLOB
Pour l'instant la réponse est que ça doit venir du serveur WEB, en effet celui-ci peut fournir un "charset" dans les entêtes HTTP
(Content-Type: text/html; charset=utf-8 ).
si ce n'est pas transmis par le serveur, HTTPGETCLOB suppose alors ISO-8859-1, soit du LATIN-1 (et non de l'UTF-8), bref du coté HTTPGETCLOB : "work as design", l'incident passe du coté support Apache.
(Content-Type: text/html; charset=utf-8 ).
si ce n'est pas transmis par le serveur, HTTPGETCLOB suppose alors ISO-8859-1, soit du LATIN-1 (et non de l'UTF-8), bref du coté HTTPGETCLOB : "work as design", l'incident passe du coté support Apache.
Christian Massé (Volubis.fr)
-
- Messages : 26
- Enregistré le : ven. 26 oct. 2018, 09:58:31
Quand je fais un :
SELECT cast(substr(RESPO00002, 1, 1500) as varchar(1500))
FROM table(SYSTOOLS.HTTPGETCLOBverbose(
'http://MonAS:10032/web/services/WS1208/abc', '')) as Reponse
j'obtiens :
<?xml version="1.0" encoding="UTF-8" ?><httpHeader responseCode="200"><responseMessage>OK
....
<header name="Content-Language" value="fr-FR"/>
...
<header name="Content-Type" value="application/json"/>
<header name="X-Powered-By" value="IBM i"/></httpHeader>
Je pensais que le : "encoding=UTF-"8 (avec le code retour=200) était la réponse du serveur Web indiquant le CCSID utilisé
J'attends la suite.
SELECT cast(substr(RESPO00002, 1, 1500) as varchar(1500))
FROM table(SYSTOOLS.HTTPGETCLOBverbose(
'http://MonAS:10032/web/services/WS1208/abc', '')) as Reponse
j'obtiens :
<?xml version="1.0" encoding="UTF-8" ?><httpHeader responseCode="200"><responseMessage>OK
....
<header name="Content-Language" value="fr-FR"/>
...
<header name="Content-Type" value="application/json"/>
<header name="X-Powered-By" value="IBM i"/></httpHeader>
Je pensais que le : "encoding=UTF-"8 (avec le code retour=200) était la réponse du serveur Web indiquant le CCSID utilisé
J'attends la suite.
Merci pour votre aide.
JYSA
JYSA
-
- Site Admin
- Messages : 813
- Enregistré le : mer. 14 févr. 2007, 18:00:03
- Localisation : Nantes
- Contact :
HEADER
ce n'est pas le XML qui est en cause, mais le retour du serveur Apache.Pour l'instant ca marche en ajoutant dans httpd.conf
(Astuce de Nathanaël BONNET)
qui force le serveur à indiquer dans l'entête HTTP que le format JSON est en UTF8 (à adapter pour le XML).
je vais voir si le point service indique plus simple ?
Code : Tout sélectionner
Header onsuccess Edit Content-type application/json "application/json; charset=utf-8"
qui force le serveur à indiquer dans l'entête HTTP que le format JSON est en UTF8 (à adapter pour le XML).
je vais voir si le point service indique plus simple ?
Christian Massé (Volubis.fr)
-
- Messages : 26
- Enregistré le : ven. 26 oct. 2018, 09:58:31
(sujet inconnu)
Bonjour,
En modifiant le fichier httpd.conf ça fonctionne correctement, tous les caractères accentués (et autres cédilles ...) fonctionnent en retour.
merci encore pour votre temps et votre analyse.
En modifiant le fichier httpd.conf ça fonctionne correctement, tous les caractères accentués (et autres cédilles ...) fonctionnent en retour.
merci encore pour votre temps et votre analyse.
Merci pour votre aide.
JYSA
JYSA
Re: HTTPGETCLOB
Donc, si ce cas se produit, il ne faut pas essayer de rebooter le système.cmasse a écrit :Pour l'instant la réponse est que ça doit venir du serveur WEB, en effet celui-ci peut fournir un "charset" dans les entêtes HTTP
(Content-Type: text/html; charset=utf-8 ).
si ce n'est pas transmis par le serveur, HTTPGETCLOB suppose alors ISO-8859-1, soit du LATIN-1 (et non de l'UTF-8) mutuelles professionnelle, bref du coté HTTPGETCLOB : "work as design", l'incident passe du coté support Apache.
Re: HEADER
Bonjour, vous parlez du httpd.conf du serveur éxécutant le webservice c'est bien ça ?cmasse a écrit :ce n'est pas le XML qui est en cause, mais le retour du serveur Apache.Pour l'instant ca marche en ajoutant dans httpd.conf(Astuce de Nathanaël BONNET)Code : Tout sélectionner
Header onsuccess Edit Content-type application/json "application/json; charset=utf-8"
qui force le serveur à indiquer dans l'entête HTTP que le format JSON est en UTF8 (à adapter pour le XML).
je vais voir si le point service indique plus simple ?
J'ai un problème identique en utilisant les webservices d'un ERP. La modification serait donc à faire sur le serveur de l'ERP ?