2015-01-06 7 views
5

Ho un'area di testo sul sito Web in cui l'utente può scrivere qualsiasi cosa. Il problema si verifica quando la copia utente incolla del testo o qualcosa che contiene caratteri non UTF 8 e li invia al server.Rimuovere caratteri non adatti alla codifica UTF-8 da String

Java lo gestisce correttamente, poiché supporta UTF-16 ma la mia tabella mySql supporta UTF-8 e pertanto l'inserimento non riesce.

Stavo cercando di implementare in qualche modo nella logica di business, per rimuovere tutti i caratteri che non sono adatti per la codifica UTF-8.

Attualmente sto usando questo codice:

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

Ma sostituisce i caratteri non adatto per UTF-8 con alcuni altri personaggi oscuri. Anche questo non sembra buono per l'utente finale. Qualcuno potrebbe per favore gettare un po 'di luce su ogni possibile soluzione per affrontare questo utilizzando il codice Java?

EDIT: Ad esempio, un'eccezione I ottenuto durante l'inserimento di tali valori

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

Può fare un esempio di un personaggio con cui hai un problema? UTF-8 e UTF-16 sono * codifiche * per lo stesso identico intervallo di caratteri, quindi non dovrebbe importare quale codifica sia supportata dal database. –

+0

@ErwinBolwidt Scusa, non ho quella stringa, l'utente ha provato ad inserire ma ho aggiunto l'eccezione che ho ottenuto con l'inserimento di due di tali stringhe – Abhi

risposta

7

UTF-8 non è un insieme di caratteri, un personaggio codifica, proprio come UTF-16.

UTF-8 è in grado di codificare qualsiasi carattere unicode e qualsiasi testo Unicode in una sequenza di byte, quindi non esistono caratteri non adatti per UTF-8.

Si utilizza un costruttore di String che richiede solo un array di byte (String(byte[] bytes)) che secondo i javadoc:

Costrutti una nuova stringa decodificando matrice specificata di byte utilizzando caratteri predefinito della piattaforma.

Utilizza il set di caratteri predefinito della piattaforma per interpretare i byte (per convertire i byte in caratteri). Non usare questo. Invece, quando si converte un array di byte in String, specificare la codifica che si desidera utilizzare esplicitamente con il costruttore String(byte[] bytes, Charset charset).

Se si verificano problemi con determinati caratteri, è molto probabile che si utilizzino set di caratteri o codifiche differenti sul lato server e sul lato client (brownser + HTML). Assicurati di utilizzare UTF-8 ovunque, non mischiare le codifiche e non utilizzare la codifica predefinita della piattaforma.

Alcune letture come raggiungere questo obiettivo:

How to get UTF-8 working in Java webapps?

+0

Grazie mille per queste informazioni, non sto mettendo alcun controllo sul modulo lato client sottomissione. Se ti prendo bene, allora dovrei usare il tag form come questo '

' e anche sulla codifica sul lato server, dovrei usare "UTF-8" invece di lasciarlo vuoto e usando l'impostazione predefinita del server ?? – Abhi

+1

Si prega di leggere la domanda collegata. Descrive in dettaglio dove e come UTF-8 dovrebbe essere fornito, non solo il tag HTML ''. – icza

+0

Grazie per l'eccellente risorsa. – Abhi

1

Il problema nel codice è che si sta chiamando new String su un byte[]. Il risultato di encode è ByteBuffer e il risultato di array su ByteBuffer è byte[]. Il costruttore new String(byte[]) utilizzerà la codifica predefinita della piattaforma per il computer; può essere diverso su ogni computer sul quale si esegue, quindi non è qualcosa che si desidera. Si dovrebbe almeno passare un set di caratteri come secondo argomento al costruttore String, anche se non sono sicuro quale set di caratteri avresti in mente.

Non sono sicuro del motivo per cui lo stai facendo: se il tuo database utilizza UTF-8, eseguirà la codifica per te. Devi solo passare le stringhe non codificate in esso.

UTF-8 e UTF-16 possono entrambi codificare l'intero set di caratteri Unicode 6; non ci sono caratteri che possono essere codificati da UTF-16 ma non da UTF-8. Quindi quella parte della tua domanda è sfortunatamente senza risposta.

Per alcuni retroscena:

0

Forse la risposta con l'CharsetDecoder di questo question aiuta. È possibile modificare lo CodingErrorAction in REPLACE e impostare una sostituzione nel mio esempio "?". Questo produrrà una determinata stringa di sostituzione per sequenze di byte non valide. In questo esempio, un UTF-8 decoder capability and stress test file viene letto e decodificato:

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);