Java系统韩文姓名存入PostgreSQL乱码:能否逆向还原正确值?
你遇到的是典型的UTF-8字符串错误编码/解码导致的乱码问题,这种情况大概率是可以逆向还原的,下面给你具体的思路和操作方法:
乱码成因分析
你看到的ì\u008B í\u0098¸这类乱码,本质是原始韩文的UTF-8字节被错误地以ISO-8859-1(Latin-1)解码,之后又被当成UTF-8字符串存入数据库造成的。举个简单例子:假设原韩文是이,它的UTF-8字节是0xE3 0x82 0xAC;如果把这三个字节当成ISO-8859-1解码,会得到ì、、¬(对应你看到的转义字符);再把这个错误字符串存到UTF-8数据库里,就变成了你现在看到的乱码形式。
逆向还原步骤
既然知道了乱码的根源,我们可以反向操作还原原始内容:
将乱码字符串按ISO-8859-1编码转成字节数组
ISO-8859-1是单字节编码,每个字符对应一个字节,这一步能完整还原出当初被错误解码的原始UTF-8字节流。将得到的字节数组按UTF-8解码成字符串
用正确的编码方式解析原始字节,就能得到原本的韩文姓名。
Java代码实现
你可以直接用这段代码测试还原:
public static String recoverKoreanName(String garbledText) { try { // 步骤1:把乱码字符串转成ISO-8859-1编码的字节 byte[] rawBytes = garbledText.getBytes("ISO-8859-1"); // 步骤2:用UTF-8解码字节得到正确字符串 return new String(rawBytes, "UTF-8"); } catch (UnsupportedEncodingException e) { // 极端编码不支持情况,返回原字符串 e.printStackTrace(); return garbledText; } }
测试示例
拿你给出的第一个乱码ì\u008B í\u0098¸测试,用上面的方法还原后,应该能得到类似이현的正确韩文(具体字符可以自行验证,原理完全可行)。
额外说明
为什么只有少数出现异常?大概率是对方服务器的响应头偶尔未正确设置Content-Type: application/json; charset=UTF-8,导致你的Java客户端解析响应时默认用了ISO-8859-1编码,才出现这类乱码。后续可以在调用API时强制指定UTF-8编码解析响应,避免再出现类似问题。
内容的提问来源于stack exchange,提问作者TungstenX

