Toon posts:

Java - UTFDataFormatException: Invalid byte 2 of 3-b

Pagina: 1
Acties:

Verwijderd

Topicstarter
In mijn programma pak in XML berichten op en trek ik daar via SAX een aantal kenmerken uit.

Dat doe ik als volgt:
Java:
1
2
3
4
5
6
7
8
9
 

private boolean informatieUitAanvraagOphalen(InputStream deStream) {
   
  try{
      DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
      Document doc = docBuilder.parse(deStream);
...
Verder niet zo interessant. Het gaat mis bij het parsen van de InputStream. Deze stream bevat dus het XML bericht, dat moge duidelijk zijn.

Dit XML bericht bevat diakritische tekens. Bijvoorbeeld: ï é ò û.... Je kent ze wel.
Daar hangt ie dus op (berichten zonder gaan wel goed). De fout boodschap die ik krijg is als volgt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java.io.UTFDataFormatException: Invalid byte 2 of 3-byte UTF-8 sequence.
  at org.apache.xerces.impl.io.UTF8Reader.invalidByte(Unknown Source)
  at org.apache.xerces.impl.io.UTF8Reader.read(Unknown Source)
  at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)
  at org.apache.xerces.impl.XMLEntityScanner.scanContent(Unknown Source)
  at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanContent(Unknown Source)
  at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
  at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
  at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
  at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
  at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
  at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
  at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
  at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
  at hatt.HDNAanvraag.informatieUitAanvraagOphalen(HDNAanvraag.java:64)
...
De XML bestanden zijn voorzien van "encoding="UTF-8" " clausule...

Ik heb al geprobeerd om de parameter "-Djava.lang.encoding=UTF-8" mee te geven als ik de applicatie start, maar dat werkt dus niet.

Enig idee hoe ik ervoor kan zorgen dat de Diakritische tekens gewoon gelezen worden?
(Zonder mijn bron XML bestanden te wijzigen dus... Die zijn nou eenmaal zo, daar kan ik niks aan doen.)

Alvast bedankt! _/-\o_

  • matthijsln
  • Registratie: Augustus 2002
  • Nu online
Er staat dan wel encoding="UTF-8" in de XML bestanden, maar zijn ze dat ook? Bekijk ze bijvoorbeeld eens met een hex editor. Een i met trema is in UTF-8 bijvoorbeeld gecodeerd met twee bytes: C3 AF.

Het meest waarschijnlijke is dat het XML bestand in een andere encoding is geschreven dan de encoding die in de XML declaratie staat. Is dat het geval zijn het geen correcte XML bestanden, dus weg ermee! Afhankelijk van hoe niet wijzigbaar je XML bestanden echt zijn kan je dan gaan klagen bij de prutsers die ongeldige bestanden maken of stinkende workarounds gaan verzinnen ;)

Verwijderd

Topicstarter
Hey Matthijs,

Bedankt.
Ik heb zojuist even gekeken en ik moet even hetvolgende erbij melden.

Ik haal de XML berichten zowel uit files als uit een database.

De XML bestanden uit de files gaan goed heb ik nu gezien (De HEX codering zoals jij hem noemde klopte daar namelijk).

Het probleem lijkt dus te verschuiven, en ik denk dat je gelijk hebt.

Of het gaat mis bij het opslaan van de berichten in de database, dat de codering gemold wordt (alhoewel ik wel netjes ' ï ' zie staan in de output van de SQL manager)

Of het gaat mis bij het lezen van de aanvraag uit de database.
(Maar als ik de String die ik daar heb, print, ziet dat er ook goed uit.)

Of het gaat fout op het moment dat ik de String in een StringBufferInputStream prop.
Ik moet immers een InputStream hebben.
(Al denk ik niet dat de fout hier zit. Ik zou niet weten waarom Java de codering aan zou passen.)

Ik denk dus dat het ergens bij het lezen of schrijven van de Databse foutgaat... Ik ga maar eens zoeken wat ik hieraan kan doen.

Bedankt! :)

  • matthijsln
  • Registratie: Augustus 2002
  • Nu online
Je kan een XML bron op twee manieren parsen:

- Als een stream van bytes. De parser leest in de XML declaratie in welke encoding de bytes zijn om er karakters van te maken. Dit doe je dus door met DocumentBuilder.parse(InputStream).

- Als een stream van characters. Hiermee wordt dus al voor dat de gegevens bij de XML parser aankomen de bytes via een encoding omgezet naar karakters. Dit doe je door een InputSource te maken met de constructor die een Reader accepteert, deze kan je dan parsen met DocumentBuilder.parse(InputSource).

Nou zeg je dat je gegevens uit een mssql database komen. Hoe je de goede encoding krijgt hangt af van hoe de XML in de database wordt opgeslagen, als bytes (BLOB, mssql: image column) of als characters (text of varchar column).

In het eerste geval dient het XML document natuurlijk goed gecodeerd als bytes te zijn opgeslagen. In het tweede geval (jou situatie denk ik) is het de bedoeling dat je JDBC driver met mssql praat zodanig dat je je XML document al als characters krijgt.

Als je een JDBC ResultSet hebt zou je iets als het volgende kunnen proberen:

InputSource xmlSource = new InputSource(resultSet.getCharacterStream("mijn_kolom"));
docBuilder.parse(xmlSource);

Verwijderd

Topicstarter
Ik ben nu helaas niet in staat om het te proberen, dus dat wordt vanavond pas.

Inderdaad wordt de aanvraag opgeslagen als varchar. (Wederom niet mijn keuze... ik moet het er maar mee doen...)

Ik heb ook al zitten kijken naar de getBinaryStream() en de getCharacterStream() methoden van de ResultSet inderdaad...

Misschien moet ik het daar eens mee proberen.

Ik heb ook iets gelezen over het zetten van een "charSet" property op het moment dat ik de Connection opvraag van de DriverManager. Bij Microsoft zie ik echter niet een dergelijke property die ik aan hun jdbc driver kan meegeven, dus dat valt nog te bezien.

Bedankt nogmaals. Vanavond ga ik het proberen!

  • matthijsln
  • Registratie: Augustus 2002
  • Nu online
Als dat niet werkt zou je een andere JDBC driver voor mssql kunnen proberen zoals jTDS, daar heb ik zelf goede ervaringen mee.

[ Voor 3% gewijzigd door matthijsln op 16-03-2006 10:15 ]


  • Standeman
  • Registratie: November 2000
  • Laatst online: 21:40

Standeman

Prutser 1e klasse

Wat je ook kan doen is kijken naar de encoding van je DB veld(en) waar je XML in opgeslagen wordt. In MSSQL valt dat onder het kopje Collation welke je kan zien in Enterprise manager / Design view.

ook zoeken met de term "encoding scheme" levert wat info op in MSDN.

suc6 iig..

* Standeman heeft nare ervaringen met encodings enzo :(

The ships hung in the sky in much the same way that bricks don’t.


Verwijderd

Topicstarter
Ok Matthijs,

De eerste optie die je gaf werkt in ieder geval.
De InputSource blijkt wel goed te parsen tov de InputStream.

Petje af dat je daar zo op deze manier opkomt! _/-\o_

Ik snap hem nog niet helemaal namelijk.
Waarom kan de InputStream niet met de diakrieten omgaan als die uit de Database komt en wel als die uit een bestand komt? In beide gevallen worden ze Byte voor Byte gelezen. Alleen de InputSource (of eigenlijk de Reader) leest per Character. Want dat is het probleem begrijp ik.

Vreemd. :?

Ik ga toch nog even kijken of ik wat kan doen met de JDBC (van Microsoft en die jij gaf) properties. Al denk ik niet dat ik daar iets mee zal bereiken.

  • matthijsln
  • Registratie: Augustus 2002
  • Nu online
Verwijderd schreef op donderdag 16 maart 2006 @ 22:11:
Ik snap hem nog niet helemaal namelijk.
Waarom kan de InputStream niet met de diakrieten omgaan als die uit de Database komt en wel als die uit een bestand komt? In beide gevallen worden ze Byte voor Byte gelezen. Alleen de InputSource (of eigenlijk de Reader) leest per Character. Want dat is het probleem begrijp ik.
Zoals je zei, het bestand was in de encoding opgeslagen die in de XML declaratie stond (UTF8):
Verwijderd schreef op donderdag 16 maart 2006 @ 07:58:
De XML bestanden uit de files gaan goed heb ik nu gezien (De HEX codering zoals jij hem noemde klopte daar namelijk).
B)

Indien je een varchar kolom als bytes gaat lezen weet je niet wat de juiste encoding daarvan is. Daarom moet je een varchar kolom dus ook lezen als characters mbv getString() of getCharacterStream(). Dan hoef je je om de encoding geen zorgen te maken, zo is de bedoeling.
Pagina: 1