IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Encodage/Decodage UTF-8 de données XML


Sujet :

Langage Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 5
    Points
    5
    Par défaut Encodage/Decodage UTF-8 de données XML
    Bonjour à tous,

    Mon application reçoit des données XML signées (XMLDSig) et comportant des caractères accentués, de plusieurs sources différentes et son comportement lors de la vérification de la signature varie selon ces sources (bien entendu, s'il n'y a aucun caractère accentué, tout va bien ). Je m'explique :

    Premier cas : les données XML sont fournies par une application externe C++ , m'assurant (mais je n'ai pas vu le code) que la chaine de caractères est encodée UTF-8, cette dernière étant construite à la volée. Si je veux que la vérification de signature fonctionne (calcul du digest, etc.), la chaine de caractères en entrée du Verifier doit être obtenue à partir de l'originale via :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xml_utf8 = new String(xml.getBytes(), "UTF-8");
    Second cas : les données XML sont fournies par un client JAVA lisant un fichier XML depuis le disque (OS : Windows XP) grâce à (merci commons-io) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    textMsg = FileUtils.readFileToString(unFichier, "UTF-8");
    Si je veux que la verification soit OK, alors je dois construire ma chaine comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xml_utf8 = new String(xml.getBytes("UTF-8"), "UTF-8");
    ou
    xml_iso-8859-15 = new String(xml.getBytes(), "ISO-8859-15");
    Mon fichier XML en entrée semble être encodé UTF-8 :
    - Notepad++ l'indique dans son menu 'Format' ;
    - UltraEdit indique en hexa que mes caractères accentués sont ceux attendus en UTF-8 hex, soit C3A9 pour é par exemple. De plus, il m'indique que le Byte Order Mark (BOM) au commencement du fichier est celui attendu : EF BB BF (cf. http://www.w3.org/TR/2004/REC-xml-20...ng-no-ext-info)

    Il y a surement une étape que je fais mal et qui introduit un peu d'ISO mais je ne vois pas comment la découvrir
    Quelqu'un peut-il m'aider ?

    D'avance merci
    Ticker

  2. #2
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    Tiens, pourquoi n'utilises-tu pas un parsing XML à base de DOM ou SAX ? Il suffit de préciser d'entrée de jeu l'encoding du fichier s'il n'est pas détecté automatiquement ou bien si tu veux le forcer. Evite de manipuler un XML sous la forme d'une String.
    Ensuite, ben il n'y a plus rien à faire. Si le fichier est mal encodé, tu auras une exception relative à l'encoding lors du parsing.

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Ceci est une aberration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xml_utf8 = new String(xml.getBytes(), "UTF-8");
    En Java une String est TOUJOURS encodé en UTF-16 en interne, et les conversions ne doivent avoir lieu que lors des entrée/sorties (dans un fichier par exemple)

    Et comme getBytes() utilises l'encodage par défaut, il est probable que tu transformes une String en un encodage différents d'UTF-8 pour l'interpréter ensuite en UTF-8


    Bref : il faut spécifier l'encodage uniquement lors de la lecture/écriture...

    a++

  4. #4
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par djsnipe Voir le message
    Tiens, pourquoi n'utilises-tu pas un parsing XML à base de DOM ou SAX ?
    Tout simplement pour des questions de vitesse et d'encombrement mémoire : je reçois une chaine de caractères que je vais transformer en objets JAVA via Castor après avoir déchiffré (XMLEnc) et vérifié (XMLDSig). L'étape DOM me semble de trop, mais si c'est le seul moyen de contrôler l'encodage...

    Citation Envoyé par adiGuba Voir le message
    En Java une String est TOUJOURS encodé en UTF-16 en interne, et les conversions ne doivent avoir lieu que lors des entrée/sorties (dans un fichier par exemple).

    Et comme getBytes() utilises l'encodage par défaut, il est probable que tu transformes une String en un encodage différents d'UTF-8 pour l'interpréter ensuite en UTF-8
    J'entends bien, mais il s'agit d'une chaine de caractères UTF-8 envoyée via WebServices depuis une application C++. L'aberration dont tu parles est le seul moyen pour que cette chaine qui n'a pas été modifiée par une source extérieure, donne le même Digest que celui calculé par l'appli C++
    Par contre, effectivement, avec un client JAVA lisant un fichier sur le disque, pas besoin de quoi que ce soit pour une vérification OK, je peux verifier directement la chaine fournie...

    J'aimerais bien savoir comment faire fonctionner les deux en même temps

    Ticker

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Comment accèdes-tu aux données transmises par le C++ ?

  6. #6
    Membre confirmé Avatar de djsnipe
    Inscrit en
    Mai 2008
    Messages
    440
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 440
    Points : 493
    Points
    493
    Par défaut
    Citation Envoyé par TickerOpcvm Voir le message
    Tout simplement pour des questions de vitesse et d'encombrement mémoire : je reçois une chaine de caractères que je vais transformer en objets JAVA via Castor après avoir déchiffré (XMLEnc) et vérifié (XMLDSig). L'étape DOM me semble de trop, mais si c'est le seul moyen de contrôler l'encodage...
    Ouf, tu utilises Castor, donc SAX qui je me souviens bien. Mais ce qui me semble étonnant c'est de passer par l'étape String. Le WebService renvoi un XML, pas directement une String, soit attaché au flux de transport, soit dans un fichier attaché. C'est directement ce flux qu'il faut utiliser et éviter si possible de tout convertir en String puis en objets Java, ce qui est de mon point de vue inutile. Mais je ne connais pas XMLEnc et XMLDSig ni leur intégration à un processus unique de parsing XML -> Java.

  7. #7
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par djsnipe Voir le message
    Ouf, tu utilises Castor, donc SAX qui je me souviens bien. Mais ce qui me semble étonnant c'est de passer par l'étape String. Le WebService renvoi un XML, pas directement une String, soit attaché au flux de transport, soit dans un fichier attaché. C'est directement ce flux qu'il faut utiliser et éviter si possible de tout convertir en String puis en objets Java, ce qui est de mon point de vue inutile. Mais je ne connais pas XMLEnc et XMLDSig ni leur intégration à un processus unique de parsing XML -> Java.
    En fait, j'ai de fortes contraintes de performances et j'ai fait au plus simple/rapide : manipuler des String pour les étapes de signature/chiffrement me fait gagner du temps. Surtout que j'ai reecrit ces dernieres pour gagner en vitesse. Par conséquent, le service exposé prend String en paramètre et non pas Document. Ce probleme de caractères accentués va peut-etre me contraindre a modifier cela, mais je dois faire des benchs avant tout.

    D'autre part, ce qui m'intéresse, ce sont les données transportées et pas la structure du XML en lui-même. Je dois pouvoir accepter une multitude de schémas différents transportant les mêmes données pour les diriger vers le même traitement. En cela, Castor et son mapping facilitent les choses Je suis donc content avec mes String (sans jeu de mot)...

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Citation Envoyé par dingoth Voir le message
    Comment accèdes-tu aux données transmises par le C++ ?
    Désolé d'insister, mais je crois que le coeur du problème réside là. Pourrais-tu répondre ?

  9. #9
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Désolé dingoth !

    En fait, l'appli C++ m'envoie une chaine de caractères théoriquement UTF-8 via WebServices sur mon appli JAVA. Il semblerait que le framework utilisé pour la génération des classes soit gSOAP...

  10. #10
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Ok, Pas de souci

    Est-ce qu'à gSOAP ou WebServices, tu indiques explicitement que tu lis de l'UTF-8 ? Ou est-ce que l'application C++, dans son texte renvoyé (oui : son texte renvoyé, pas sa documentation), dit explicitement qu'elle renvoie de l'UTF-8 ?

  11. #11
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Les seules indications dont je dispose sont l'entête du document XML
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?xml version="1.0" encoding="UTF-8"?>
    et le fait que la ligne de code aberrante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xml_utf8 = new String(xml.getBytes(), "UTF-8");
    remet les caractères accentués d'aplomb. Ce qui permet de calculer un Digest de signature identique à celui obtenu par l'appli C++ avant l'envoi, me garantissant l'intégrité du message.

    Pour le reste, je ne fais que manipuler des String dans mon implémentation métier (C'est JAX-RPC qui se charge des traitements purement SOAP). Il faut que la ligne précédente ne soit pas executée pour que cela fonctionne avec mon client WebServices JAVA ...

  12. #12
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par TickerOpcvm Voir le message
    et le fait que la ligne de code aberrante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xml_utf8 = new String(xml.getBytes(), "UTF-8");
    remet les caractères accentués d'aplomb.
    Non non et non ! Tu n'as pas dû bien lire mon message !

    Si cela te corrige quelque chose cela voudrait dire que c'est la chaine xml qui est mal formé.

    Car avec ce code il y a deux cas possibles :
    • Soit l'encodage système est UTF-8 (souvent le cas sous les systèmes GNU/Linux), et dans ce cas cela donnera exactement la même chaine.
    • Soit l'encodage système n'est pas de l'UTF-8 (comme sous Windows avec son cp1252), et dans ce cas tu vas convertir la chaine en cp1252 pour l'interpréter comme de l'utf8





    Bref je le redis : si tu as un problème c'est sur tes accès en lecture/écriture.
    En clair : comment tu obtiens ta String "xml" ?


    a++

  13. #13
    Futur Membre du Club
    Inscrit en
    Février 2003
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Non non et non ! Tu n'as pas dû bien lire mon message !
    Bref je le redis : si tu as un problème c'est sur tes accès en lecture/écriture.
    En clair : comment tu obtiens ta String "xml" ?
    Non, non, pas taper !!

    Plus sérieusement, la chaine "xml" qui nécessite cette bidouille est obtenue comme je l'ai précisé à dingoth
    En fait, l'appli C++ m'envoie une chaine de caractères théoriquement UTF-8 via WebServices sur mon appli JAVA. Il semblerait que le framework utilisé pour la génération des classes soit gSOAP...
    De mon coté, JAX-RPC décapsule SOAP et me fournit la fameuse chaine "xml" attendue en paramètre d'entrée de mon traitement. Je n'ai pas la moindre idée de ce qui est fait en termes de désérialisation par exemple avant de récupérer cette chaine.
    Mais cela me fournit une piste (surtout qu'avec un client JAVA, je le répète, pas besoin de bidouille) : je vais tracer dans les classes de manipulation SOAP générées coté serveur WebServices...

    Ticker

Discussions similaires

  1. [Mysql] Donnée XML >vers> BDD
    Par largiss dans le forum XQUERY/SGBD
    Réponses: 14
    Dernier message: 28/02/2017, 18h51
  2. [DOM] Encodage UTF-8 dans fichier XML et PHP
    Par norkius dans le forum Bibliothèques et frameworks
    Réponses: 7
    Dernier message: 03/01/2007, 16h44
  3. Où est l'Expert Liaison de données XML [BCB6]
    Par Colloc dans le forum C++Builder
    Réponses: 3
    Dernier message: 21/02/2005, 15h33
  4. [xml]manipuler des données xml sous Oracle9i
    Par crazy dans le forum SQL
    Réponses: 7
    Dernier message: 28/02/2004, 12h40
  5. problème xsl : inclure une donnée xml dans une balise html
    Par djodjo dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 03/01/2003, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo