java - 如何使用Java直接使用字符集对字节数组进行编码/解码/转码

标签 java mysql jdbc character-encoding malformed

我有一个格式错误的字符串,这可能是由 MySQL JDBC 驱动程序的一个错误引起的,

示例畸形字符串 (malformed_string.getBytes("UTF-8")) 的字节是这样的:

C3 A4 C2 B8 C2 AD C3 A6 E2 80 93 E2 80 A1  (UTF-8 twice)

应该对以下字节进行编码(它已经是 UTF-8 编码,但将它们视为 ISO-8859-1 编码)

----- ----- ----- ----- -------- --------
  E4   B8    AD     E6     96       87     (UTF-8)

应该对以下 Unicode BigEndian 字节进行编码

---------------     ---------------------
     4E 2D                65 87            (Unicode BigEndian)

我想将第一个解码为第二个,我尝试了 new String(malformed_string.getBytes("UTF-8"), "ISO-8859-1"),但确实如此没有按预期转码。想知道有没有byte[] encode/decode (byte[] src, String charsetName)之类的,或者如何在java中实现上面的转码?

背景:

我有一个包含中文列名的 MySQL 表,当我用长数据更新这些列时,MySQL JDBC 驱动程序抛出如下异常:

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column '中文' at row 1

异常中的列名格式错误,应为“中文”,必须正确显示给用户,如下所示。

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column '中文' at row 1

编辑

下面是 MySQL 语句,用于演示格式错误的字符串是如何发生的,以及如何将其恢复为正确的字符串

show variables like 'char%';
+--------------------------+--------------------------+
| Variable_name            | Value                    |
+--------------------------+--------------------------+
| character_set_client     | utf8                     |
| character_set_connection | utf8                     |
| character_set_database   | utf8                     |
| character_set_filesystem | binary                   |
| character_set_results    | utf8                     |
| character_set_server     | utf8                     |
| character_set_system     | utf8                     |
| character_sets_dir       | C:\mysql\share\charsets\ |
+--------------------------+--------------------------+

-- encode
select
    hex(convert(convert(unhex('E4B8ADE69687') using UTF8) using ucs2)) as `hex(src in UNICODE)`,
    unhex('E4B8ADE69687') `src in UTF8`,
    'E4B8ADE69687' `hex(src in UTF8)`,
    hex(convert(convert(unhex('E4B8ADE69687') using latin1) using UTF8)) as `hex(src in UTF8->Latin1->UTF8)`;
+---------------------+-------------+------------------+--------------------------------+
| hex(src in UNICODE) | src in UTF8 | hex(src in UTF8) | hex(src in UTF8->Latin1->UTF8) |
+---------------------+-------------+------------------+--------------------------------+
| 4E2D6587            | 中文        | E4B8ADE69687     | C3A4C2B8C2ADC3A6E28093E280A1   |
+---------------------+-------------+------------------+--------------------------------+
1 row in set (0.00 sec)


-- decode
select
    unhex('C3A4C2B8C2ADC3A6E28093E280A1') as `malformed`,
    'C3A4C2B8C2ADC3A6E28093E280A1' as `hex(malformed)`,
    hex(convert(convert(unhex('C3A4C2B8C2ADC3A6E28093E280A1') using utf8) using latin1)) as `hex(malformed->UTF8->Latin1)`,
    convert(convert(convert(convert(unhex('C3A4C2B8C2ADC3A6E28093E280A1') using utf8) using latin1) using binary)using utf8) `malformed->UTF8->Latin1->binary->UTF8`;
+----------------+------------------------------+------------------------------+---------------------------------------+
| malformed      | hex(malformed)               | hex(malformed->UTF8->Latin1) | malformed->UTF8->Latin1->binary->UTF8 |
+----------------+------------------------------+------------------------------+---------------------------------------+
| 中文         | C3A4C2B8C2ADC3A6E28093E280A1 | E4B8ADE69687                 | 中文                                  |
+----------------+------------------------------+------------------------------+---------------------------------------+
1 row in set (0.00 sec)

最佳答案

查看本教程:http://download.oracle.com/javase/tutorial/i18n/text/string.html

重点是仅使用 jdk 类进行转码的方法是:

try {
byte[] utf8Bytes = original.getBytes("UTF8");
byte[] defaultBytes = original.getBytes();

String roundTrip = new String(utf8Bytes, "ISO-885-9");
System.out.println("roundTrip = " + roundTrip);
System.out.println();
printBytes(utf8Bytes, "utf8Bytes");
System.out.println();
printBytes(defaultBytes, "defaultBytes");
} catch (UnsupportedEncodingException e) {
 e.printStackTrace();
}

对于更强大的转码机制,我建议您查看 ICU>

关于java - 如何使用Java直接使用字符集对字节数组进行编码/解码/转码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7500616/

相关文章:

java - 如何使用 Webflux 上传多个文件?

java - 如何验证 java 中的文本字段

mysql - Docker设置mysql db

mysql - 由于另一个表中不存在记录而从一个表中删除记录

java - 使用 JDBC 和 JSP 的 UPSERT MYSQL 命令

java - MySQL java jdbc MySQLNonTransientConnectionException : Got packets out of order

java - 使用数组对有界集进行添加/删除操作的最坏情况的时间复杂度?

version - 我需要安装JRE8吗

php - MySQL - 我如何/解决方法按组函数的结果排序

java - 如何在jBoss BPM套件流程中访问MySQL数据库