Web Service RPGLE Probleme CCSID

configuration Apache, Zend et PHP , Web services
Répondre
jysaulieres
Messages : 26
Enregistré le : ven. 26 oct. 2018, 09:58:31

Web Service RPGLE Probleme CCSID

Message par jysaulieres »

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.
Merci pour votre aide.
JYSA

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

CCSID

Message par cmasse »

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
{"version":"1","nb_results":569,"data":[{ "geo" : { "name" : "Collège Anne de Bretagne"} ...
le "è" de collège est-il correct ?
Christian Massé (Volubis.fr)

jysaulieres
Messages : 26
Enregistré le : ven. 26 oct. 2018, 09:58:31

Message par jysaulieres »

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)
Merci pour votre aide.
JYSA

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

CCSID

Message par cmasse »

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

Code : Tout sélectionner

**free
dcl-s retour SQLTYPE&#40;CLOB &#58; 200&#41;;

exec sql
  values &#40;systools.httpgetClob&#40;'http&#58;//as400&#58;10052/web/services/TESTCCSID/abc', ''&#41;&#41;
    into &#58;retour;

dsply &#40;%subst&#40;retour_data &#58; 1 &#58; 50&#41;&#41;;
*INLR = *ON;  
                     
toujours le même problème dans retour_data

puis j'ai essayé

Code : Tout sélectionner

create table retourT &#40;retour clob CCSID 1208&#41;
et
insert into retourT values&#40;                              
   systools.httpgetClob&#40;                                 
     'http&#58;//as400&#58;10052/web/services/TESTCCSID/abc', ''&#41;
 &#41;                                                       
enfin

Code : Tout sélectionner

**free
dcl-s retour SQLTYPE&#40;DBCLOB_file&#41;;

retour_name = '/temp/retour.json';
retour_nl = %len&#40;%trim&#40;retour_name&#41;&#41;;
retour_fo = SQFOVR;

exec sql
  values &#40;systools.httpgetClob&#40;'http&#58;//as400&#58;10052/web/services/TESTCCSID/abc', ''&#41;&#41;
    into &#58;retour;

*INLR = *ON;   
                  
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.
Christian Massé (Volubis.fr)

jysaulieres
Messages : 26
Enregistré le : ven. 26 oct. 2018, 09:58:31

Message par jysaulieres »

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 )
Merci pour votre aide.
JYSA

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

Point service

Message par cmasse »

je pense que ça vaut le coup d'ouvrir un incident au point service.

je m'y colle ! (mais ça risque d'être long)
Christian Massé (Volubis.fr)

jysaulieres
Messages : 26
Enregistré le : ven. 26 oct. 2018, 09:58:31

Message par jysaulieres »

Merci encore pour votre analyse et pour l'ouverture du ticket au point service. Je vais suivre avec intérêt la suite donnée par IBM.
Merci pour votre aide.
JYSA

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

HTTPGETCLOB

Message par cmasse »

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.
Christian Massé (Volubis.fr)

jysaulieres
Messages : 26
Enregistré le : ven. 26 oct. 2018, 09:58:31

Message par jysaulieres »

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.
Merci pour votre aide.
JYSA

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

HEADER

Message par cmasse »

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

Code : Tout sélectionner

Header onsuccess Edit Content-type application/json "application/json; charset=utf-8"
(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 ?
Christian Massé (Volubis.fr)

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

Header

Message par cmasse »

Réponse du point service
So Http server needs to have : Header set Content-Type "application/json;charset=UTF-8"
Christian Massé (Volubis.fr)

jysaulieres
Messages : 26
Enregistré le : ven. 26 oct. 2018, 09:58:31

(sujet inconnu)

Message par jysaulieres »

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.
Merci pour votre aide.
JYSA

Luciad58
Messages : 1
Enregistré le : mar. 05 nov. 2019, 10:34:31

Re: HTTPGETCLOB

Message par Luciad58 »

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.
Donc, si ce cas se produit, il ne faut pas essayer de rebooter le système.

MattB
Messages : 5
Enregistré le : ven. 22 nov. 2019, 11:33:45

Re: HEADER

Message par MattB »

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

Code : Tout sélectionner

Header onsuccess Edit Content-type application/json "application/json; charset=utf-8"
(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 ?
Bonjour, vous parlez du httpd.conf du serveur éxécutant le webservice c'est bien ça ?
J'ai un problème identique en utilisant les webservices d'un ERP. La modification serait donc à faire sur le serveur de l'ERP ?

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

Re: Web Service RPGLE Probleme CCSID

Message par cmasse »

Oui, c'est cela.
Christian Massé (Volubis.fr)

Répondre