La codificación UTF8 principios y lista blanca filtra utf8mb4 (Causada por: java.sql.BatchUpdateException: valor de cadena incorrecta)

En estos días se encontraron datos de MySQL reportados para caer error de codificación:

Caused by: java.sql.BatchUpdateException: Incorrect string value: '\xF0\x9F\x98\x8A',...' for column 'statement_text' at row 1

Caused by: java.sql.BatchUpdateException: Incorrect string value: '\xF0\xA0\x81\x81%'...' for column 'statement_sample' at row 1

Internet proporciona la mayor parte de la solución es modificar la base de datos de configuración, pero la base de datos si la agrupación de conexiones no puede garantizar que no se especifica UTF-8 Shi otras conexiones, no se puede evitar la contaminación de otras conexiones de la agrupación de conexiones. Aquí hay otra solución, filtrando los caracteres especiales.

segmento 1 codificación UTF-8

UTF-8 (8-bit Unicode Transformation Format) es un carácter Unicode de longitud variable para la codificación, también un código de prefijo. Se puede utilizar para representar cualquier carácter en el estándar Unicode, y la codificación del primer byte sigue siendo compatible con ASCII, lo que hace que el software de manejo de los caracteres ASCII originales no necesitan o sólo una pequeña parte de los cambios, se puede seguir utilizando. Por lo tanto, se ha convertido gradualmente electrónica codificada, páginas web y otros prioritaria adoptada almacenamiento o enviar mensajes de texto.

1.0 Símbolos métodos de consulta

http://www.fileformat.info/info/unicode/char/xxxxx/index.htm

Reemplazar necesidad xxxx a consulta carácter hexadecimal codificación

SONRIENTE CARA ejemplo emoji de codificación es 1f60a: dirección de investigación
de carácter se codifica como 61: consulta de dirección

1.1 ASCII

sólo 128 caracteres US-ASCII una codificación byte (rango Unicode de U + 0000 a U + 007F)

por ejemplo

Hex (JAVA) gráfico
“\ U0060” `
“\ U0061” una
“\ U0062” si
"\ U0063" C
“\ U0064” re
“\ U0065” mi

1.2 América, etc.

América con los símbolos adicionales, griego, cirílico, armenio, hebreo, árabe, siríaco y Thaana necesita dos bytes de codificación Unicode (rango de U + 0080 a U + 07FF ).

Hex (JAVA) gráfico conexión de consultas
“\ U0550” T enlace
“\ U0450” o enlace

1.3 chino, etc.

Otros caracteres plano multilingüe básico (BMP) (que incluye la mayoría de las palabras comúnmente usadas, tales como la mayoría de los caracteres chinos) usando tres bytes que codifican (rango Unicode de U + 0800 a U + FFFF).

Hex (JAVA) gráfico conexión de consultas
"\ U9AD8" alto enlace
"\ U738B" rey enlace

1.4 Otros

Otros caracteres Unicode utiliza raramente plano auxiliar usando cinco y cincuenta y seis codificación byte (rango Unicode de U + 10.000 a U + 1FFFFF usando cuatro bytes, gama Unicode de U + 200.000 para uso U + 3FFFFFF de cinco bytes, gama Unicode de T + 4000000 a U + 7FFFFFFF utilizando seis bytes).

Hex (JAVA) gráfico conexión de consultas
“\ UD83D \ uDE0A” ? enlace
"\ UD83D \ uDE0F" ? enlace

2 codificación UTF-8 Byte Significado

  • Para la codificación UTF-8 cualquier byte B, B si el primer bit es 0, entonces B representan independientemente un personaje (código ASCII);
  • Si el primer bit B es 1, el segundo bit es 0, el byte B es un (caracteres no ASCII) en un carácter multi-byte;
  • Si la primera dos bits B es 1, el tercer bit es 0, entonces B es un carácter de dos bytes representado por el primer byte;
  • Si la parte superior de tres B es 1, el cuarto bit es 0, el carácter B es tres bytes en el primer byte;
  • Si los primeros cuatro bits de B 1, el quinto bit es 0, entonces B está representado por cuatro bytes en el primer byte del carácter;

Por lo tanto, para cualquier byte codificación UTF-8, de acuerdo con la primera, se puede determinar si en caracteres ASCII, el byte carácter es un byte codificada de acuerdo con la anterior primera dos, se puede determinar; El primero de cuatro bit (si los dos primeros bits son 1), puede determinar que el primer byte es una codificación de caracteres byte, y puede determinar un carácter correspondiente representado por varios bytes; los primeros cinco (si los primeros cuatro bits 1 ), no se puede determinar si el error de datos codificados o si hay un error durante la transmisión.

punto de código dígitos valores de los puntos de código de Valor final punto de código Secuencia de bytes byte 1 byte 2 byte 3 byte 4 byte 5 byte 6
7 U + 0000 U + 007F 1 0xxxxxxx
11 U + 0080 U + 07FF 2 110xxxxx 10xxxxxx
dieciséis U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
21 U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
26 U + 200000 U + 3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
31 T + 4000000 U + 7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  • En el rango de código ASCII, con un byte más allá del rango ASCII, que dice bytes, que formaron la representación que hemos visto más arriba, UTF-8, el beneficio es sólo cuando el código ASCII de archivo Unicode, los archivos se almacenan como un byte, que no es diferente de un archivo ASCII ordinario, cuando se lee es cierto, es compatible con el archivo ASCII anterior.
  • Mayor que el código ASCII, indicará la longitud del carácter Unicode por los ex primeros bytes de lo anterior, tales como la representación binaria de los tres primeros 110xxxxx nos dijo que era una 2Byte el carácter Unicode; 1110xxxx era tres de caracteres Unicode, y así sucesivamente; posiciones de bits xxx representados por la codificación de caracteres de números binarios llenados. El derecho de x tiene menos significado especial. La expresión de un personaje con sólo un número suficiente de secuencia multi-byte que codifica el más corto. Tenga en cuenta que en la cadena de múltiples bytes, un número de comienzo del primer byte "1" es un número entero de bytes de la cadena.

3 el Java filtro 4 UTF-8 codificada longitud de palabra de caracteres (longitud de palabra reservada carácter 3)

  • Como se mencionó en el anterior 1.2 y 1.3, la codificación ha conservado sus caracteres regulares longitud decir, utilizar una lista blanca para retener esta parte de las necesidades de carácter encuentro de negocios en general, filtran cadenas específicas (MySQL para resolver el problema de los caracteres especiales no se puede insertar ).

  • 4 palabras personaje es Unicode UTF-8 caracteres del SMP (plano auxiliar) que es mayor que los caracteres del código Unicode U + FFFF, así que sólo necesitamos conseguir una cadena de caracteres de cada punto de código, cuando el código de punto mayor que FFFF (o directamente utilizado para determinar Character.isSupplementaryCodePoint), se puede filtrar.

Código de la muestra es la siguiente:

    @Test
    public void filterUtf8mb4Test() {
        String s = "a中\uD83D\uDD11a中";
        log.info(filterUtf8mb4(s));
    }

    public static String filterUtf8mb4(String str) {
        final int LAST_BMP = 0xFFFF;
        StringBuilder sb = new StringBuilder(str.length());
        for (int i = 0; i < str.length(); i++) {
            int codePoint = str.codePointAt(i);
            if (codePoint < LAST_BMP) {
                sb.appendCodePoint(codePoint);
            } else {
                i++;
            }
        }
        return sb.toString();
    }

La salida es:

a中a中

4 Algunas notas

No quiero reiniciar el programa

Realizar lo siguiente en la sesión actual antes de realizar la segunda elección

set character_set_client = utf8mb4;

SET NAMES utf8mb4;

expediente de modificación del servidor

(Para cambiar todo el, cambio durante el reinicio)

[client] 
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4 
collation-server = utf8mb4_unicode_ci
[mysql] 
default-character-set = utf8mb4

Consulte la documentación oficial de
MySQL Campo Significado
parámetro
juego de caracteres

SQL para modificar el juego de caracteres

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(length) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

5 referencias

Conjunto de caracteres de origen de datos
https://zh.wikipedia.org/wiki/UTF-8
http://www.fileformat.info
https://www.cnblogs.com/chrischennx/p/6623610.html
modificar bases de datos por favor referencia
https://blog.csdn.net/hzw19920329/article/details/55670782

Publicado 27 artículos originales · ganado elogios 2 · Vistas a 50000 +

Supongo que te gusta

Origin blog.csdn.net/jackgo73/article/details/89957646
Recomendado
Clasificación