Ich erhalte diese Zeichenfolge über einen Message Broker (Stomp):
João
und so soll es auch sein:
João
Gibt es eine Möglichkeit, dies in Java rückgängig zu machen? Danke!
Ich erhalte diese Zeichenfolge über einen Message Broker (Stomp):
João
und so soll es auch sein:
João
Gibt es eine Möglichkeit, dies in Java rückgängig zu machen? Danke!
U+00C3 Ã c3 83 LATIN CAPITAL LETTER A WITH TILDE
U+00C2 Â c3 82 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
U+00A3 £ c2 a3 POUND SIGN
U+00E3 ã c3 a3 LATIN SMALL LETTER A WITH TILDE
Ich habe Schwierigkeiten, herauszufinden, wie dies ein Problem bei der Datenkonvertierung (Kodierung) sein könnte. Ist es möglich, dass die Daten einfach schlecht sind?
Wenn die Daten nicht schlecht sind, müssen wir davon ausgehen, dass Sie die Kodierung falsch interpretieren. Wir kennen die ursprüngliche Kodierung nicht, und wenn Sie nichts anderes machen, ist die Standardkodierung für Java UTF-16. Ich wüsste nicht, wie João
kodiert in jeder gängigen Kodierung könnte als João
in UTF-16
Nur um sicher zu gehen, habe ich dieses Python-Skript erstellt und keine Übereinstimmung gefunden. Ich bin nicht vollständig sicher, dass es alle Kodierungen abdeckt, oder ich übersehe keinen Eckfall, FWIW.
#!/usr/bin/env python
# -- coding: utf-8 --
import pkgutil
import encodings
good = u'João'
bad = u'João'
false_positives = set(["aliases"])
found = set(name for imp, name, ispkg in pkgutil.iter_modules(encodings.__path__) if not ispkg)
found.difference_update(false_positives)
print found
for x in found:
for y in found:
res = None
try:
res = good.encode(x).decode(y)
print res,x,y
except:
pass
if not res is None:
if res == bad:
print "FOUND"
exit(1)
In manchen Fällen funktioniert ein Hack. Aber am besten ist es, es gar nicht erst geschehen zu lassen.
Ich hatte dieses Problem vor, wenn ich ein Servlet, das korrekt die richtigen Header und http-Inhaltstyp und Codierung auf der Seite gedruckt hatte, aber IE würde Formulare mit latin1 anstelle der richtigen codiert senden. Also habe ich einen schnellen, schmutzigen Hack erstellt (mit einem Request Wrapper, der erkennt und konvertiert, ob es sich tatsächlich um den IE handelt), um das Problem für neue Daten zu beheben, was gut funktionierte. Und für die Daten in der Datenbank, die bereits in Unordnung geraten waren, habe ich den folgenden Hack verwendet.
Leider funktioniert mein Hack nicht perfekt für Ihre Beispielzeichenkette, aber es sieht sehr ähnlich aus (nur ein zusätzliches à in Ihrer kaputten Zeichenkette im Vergleich zu meiner "theoretischen Ursache" reproduzierten kaputten Zeichenkette). Vielleicht ist meine Vermutung von "latin1" also falsch, und Sie sollten andere ausprobieren (wie in dem anderen von Tomas geposteten Link).
package peter.test;
import java.io.UnsupportedEncodingException;
/**
* User: peter
* Date: 2012-04-12
* Time: 11:02 AM
*/
public class TestEncoding {
public static void main(String args[]) throws UnsupportedEncodingException {
//In some cases a hack works. But best is to prevent it from ever happening.
String good = "João";
String bad = "João";
//this line demonstrates what the "broken" string should look like if it is reversible.
String broken = breakString(good, bad);
//here we show that it is fixable if broken like breakString() does it.
fixString(good, broken);
//this line attempts to fix the string, but it is not fixable unless broken in the same way as breakString()
fixString(good, bad);
}
private static String fixString(String good, String bad) throws UnsupportedEncodingException {
byte[] bytes = bad.getBytes("latin1"); //read the Java bytes as if they were latin1 (if this works, it should result in the same number of bytes as java characters; if using UTF8, it would be more bytes)
String fixed = new String(bytes, "UTF8"); //take the raw bytes, and try to convert them to a string as if they were UTF8
System.out.println("Good: " + good);
System.out.println("Bad: " + bad);
System.out.println("bytes1.length: " + bytes.length);
System.out.println("fixed: " + fixed);
System.out.println();
return fixed;
}
private static String breakString(String good, String bad) throws UnsupportedEncodingException {
byte[] bytes = good.getBytes("UTF8");
String broken = new String(bytes, "latin1");
System.out.println("Good: " + good);
System.out.println("Bad: " + bad);
System.out.println("bytes1.length: " + bytes.length);
System.out.println("broken: " + broken);
System.out.println();
return broken;
}
}
Und das Ergebnis (mit Sun jdk 1.7.0_03):
Good: João
Bad: João
bytes1.length: 5
broken: João
Good: João
Bad: João
bytes1.length: 5
fixed: João
Good: João
Bad: João
bytes1.length: 6
fixed: Jo£o
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.