2015-01-06 3 views
5

Ich habe einen Textbereich auf der Website, auf dem der Benutzer etwas schreiben kann. Das Problem tritt auf, wenn Benutzer Text oder etwas, das Nicht-UTF-8-Zeichen enthält, kopieren und an den Server senden.Entfernen Sie Zeichen, die für die UTF-8-Codierung nicht geeignet sind, aus String

Java behandelt es erfolgreich, da es UTF-16 unterstützt, aber meine mySql-Tabelle UTF-8 unterstützt und daher Einfügung fehlschlägt.

Ich habe versucht, einen Weg in Business-Logik selbst zu implementieren, um alle Zeichen zu entfernen, die nicht für UTF-8-Codierung geeignet ist.

Derzeit bin ich mit diesem Code:

new String(java.nio.charset.Charset.forName("UTF-8").encode(myString).array()); 

Aber es ersetzt Zeichen nicht geeignet für UTF-8 mit einigen anderen unverständlichen Zeichen. Was für Endverbraucher auch nicht gut aussieht. Könnte jemand bitte etwas Licht über eine mögliche Lösung werfen, um dies mit Java-Code anzugehen?

EDIT: Zum Beispiel Ausnahme habe ich während Einfügung solcher Werte

java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\x0D\x0A...' for column 

java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x80\xF0\x9F...' for column 
+2

Können Sie ein Beispiel für eine geben Zeichen, mit dem Sie ein Problem haben? UTF-8 und UTF-16 sind * Kodierungen * für den genau gleichen Zeichenbereich. Es sollte also nicht darauf ankommen, welche Kodierung von Ihrer Datenbank unterstützt wird. –

+0

@ErwinBolwidt Entschuldigung, ich habe diese Zeichenfolge nicht, Benutzer versucht, einzufügen, aber ich habe die Ausnahme hinzugefügt, die ich bei der Einfügung von zwei solcher Zeichenfolgen bekam – Abhi

Antwort

7

UTF-8 kein Zeichensatz ist, ist es ein Zeichen Codierung, wie UTF-16.

UTF-8 kann jedes Unicode-Zeichen und jeden Unicode-Text in eine Bytefolge codieren, daher gibt es keine Zeichen, die nicht für UTF-8 geeignet sind.

Sie verwenden einen Konstruktor von String die nur einen Byte-Array nimmt (String(byte[] bytes)), die entsprechend die javadocs:

Konstrukte eine neue Zeichenfolge mit dem angegebenen Byte-Array Dekodieren der Standard-Zeichensatz der Plattform unter Verwendung von.

Es verwendet den Standardzeichensatz der Plattform, um die Bytes zu interpretieren (um die Bytes in Zeichen zu konvertieren). Benutze das nicht. Wenn Sie ein Byte-Array in String konvertieren, geben Sie stattdessen die Codierung an, die Sie explizit mit dem String(byte[] bytes, Charset charset)-Konstruktor verwenden möchten.

Wenn Sie Probleme mit bestimmten Zeichen haben, liegt das wahrscheinlich an der Verwendung unterschiedlicher Zeichensätze oder Codierungen auf der Serverseite und auf der Clientseite (brownser + HTML). Stellen Sie sicher, dass Sie UTF-8 überall verwenden, mischen Sie keine Kodierungen und verwenden Sie nicht die Standardkodierung der Plattform.

Einige Lesungen, wie dies zu erreichen: ist

How to get UTF-8 working in Java webapps?

+0

Vielen Dank für diese Erkenntnisse, ich überprüfe keine clientseitige Form Einreichung. Wenn ich dich richtig verstehe, dann sollte ich Form-Tag wie diese '

' und auch auf der Server-Seite verwenden, sollte ich "UTF-8" verwenden, anstatt es leer zu lassen und Server-Standard verwenden? – Abhi

+1

Bitte lesen Sie die verlinkte Frage. Es zeigt an, wo und wie UTF-8 bereitgestellt werden sollte, nicht nur das HTML-Symbol "". – icza

+0

Vielen Dank für die hervorragende Ressource. – Abhi

1

Das Problem in Ihrem Code, dass Sie new String auf einem byte[] anrufen. Das Ergebnis von encode ist ein ByteBuffer, und das Ergebnis von array auf einem ByteBuffer ist ein byte[]. Der Konstruktor new String(byte[]) verwendet die Standardkodierung der Plattform für Ihren Computer. Es kann auf jedem Computer, auf dem Sie laufen, anders sein, also ist das nicht etwas, das Sie wollen. Sie sollten mindestens einen Zeichensatz als zweites Argument an den Zeichenfolgenkonstruktor übergeben, obwohl ich nicht sicher bin, welchen Zeichensatz Sie im Sinn haben.

Ich bin nicht sicher, warum Sie es tun: Wenn Ihre Datenbank UTF-8 verwendet, wird es die Codierung für Sie tun. Sie müssen nur nicht codierte Strings eingeben.

UTF-8 und UTF-16 können beide den gesamten Unicode 6-Zeichensatz codieren; Es gibt keine Zeichen, die von UTF-16, aber nicht von UTF-8 codiert werden können. Dieser Teil Ihrer Frage ist leider nicht zu beantworten.

Für einige Hintergrund:

0

Vielleicht ist die Antwort mit der CharsetDecoder dieser question hilft. Sie könnten die CodingErrorAction zu REPLACE ändern und einen Ersatz in meinem Beispiel "?" Festlegen. Dies gibt eine gegebene Ersetzungszeichenfolge für ungültige Bytefolgen aus. In diesem Beispiel wird ein UTF-8 decoder capability and stress test file gelesen und decodiert:

CharsetDecoder utf8Decoder = Charset.forName("UTF-8").newDecoder(); 
utf8Decoder.onMalformedInput(CodingErrorAction.REPLACE); 
utf8Decoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 
utf8Decoder.replaceWith("?"); 

// Read stress file 
Path path = Paths.get("<path>/UTF-8-test.txt"); 
byte[] data = Files.readAllBytes(path); 
ByteBuffer input = ByteBuffer.wrap(data); 

// UTF-8 decoding 
CharBuffer output = utf8Decoder.decode(input); 

// Char buffer to string 
String outputString = output.toString(); 

System.out.println(outputString); 
Verwandte Themen