2012-04-11 9 views
3

Ich erhalte diese Zeichenfolge über einen Message-Broker (Stomp):Gibt es eine Möglichkeit, falsch codierte Strings zu reparieren?

João 

und das ist, wie es sein suposed:

João 

Gibt es eine Möglichkeit, dies in Java zurückzukehren ?! Danke!

+1

Was ein Broker ist? –

+1

Siehe http://stackoverflow.com/questions/2622911/fix-string-encoding-in-java – user219882

+0

Message-Broker (aktiv mq) ... Der Punkt ist, dass ich die andere Seite des Codes nicht berühren kann, und Ich muss nur diese Zeichenfolge beheben ... – joaoricardo000

Antwort

4
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 Probleme zu bestimmen, wie dies ein Daten (Codierung) Konvertierungsproblem sein könnte. Ist es möglich, dass die Daten nur schlecht sind?

Wenn die Daten nicht schlecht sind, müssen Sie davon ausgehen, dass Sie die Codierung falsch interpretieren. Wir kennen die ursprüngliche Codierung nicht und wenn Sie nicht etwas anderes machen, ist die Standardcodierung für Java UTF-16. Ich sehe nicht, wie João in jeder gebräuchlichen Codierung codiert werden könnte als João in UTF-16

Nur um sicher zu sein, peitschte ich dieses Python-Skript ohne Übereinstimmung gefunden. Ich bin nicht ganz sicher, es deckt alle Codierungen ab, oder ich vermisse 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) 
+0

Danke für die Antwort, ich schätze Sie efford. Aber ich muss sowieso die andere Seite des Codes ändern. Ich habe nur herausgefunden, ob es einen leichten Ausweg gibt, um das nicht zu tun – joaoricardo000

2

In einigen Fällen funktioniert ein Hack. Aber am besten ist es zu verhindern, dass es jemals passiert.

Ich hatte dieses Problem zuvor, als ich ein Servlet hatte, das korrekt die richtigen Header und HTTP-Inhaltstyp und Codierung auf der Seite gedruckt, aber IE würde Formulare mit latin1 statt der richtigen kodieren. Also habe ich einen schnellen Dirty-Hack erstellt (mit einem Request-Wrapper, der erkennt und konvertiert, wenn es tatsächlich IE ist), um ihn für neue Daten zu reparieren, die gut funktionierten. Und für die Daten in der Datenbank, die bereits durcheinander waren, benutzte ich den folgenden Hack.

Leider funktioniert mein Hack nicht perfekt für Ihre Beispiel-String, aber es sieht sehr eng (nur ein extra à in Ihrer gebrochenen Saite im Vergleich zu meiner 'theoretischen Ursache' reproduziert gebrochene Saite). Vielleicht ist meine Schätzung von "latin1" falsch, und Sie sollten andere versuchen (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 
Verwandte Themen