我们通过接口传递webservice后,它返回信息为"涓婁紶鎴愬姛!"
乱码是以Unicode形式展现的中文,它的Utf-8形式的字节码16进制为:
00000000h: E4 B8 8A E4 BC A0 E6 88 90 E5 8A 9F 21 ; 涓婁紶鎴愬姛!..
| 乱码字符 | GBK 编码 (十六进制) |
|----------|---------------------|
| 涓 | `E4 B8` |
| 婁 | `8A E4` |
| 紶 | `BC A0` |
| 鎴 | `E6 88` |
| 夽 | `90 E5` |
| 姛 | `8A 9F` |
同样的还可以将这个16进制用UTF-8 格式每三个字节码显示一个中文:
E4 B8 8A → "上"
E4 BC A0 → "传"
E6 88 90 → "成"
E5 8A 9F → "功"
21 → "!"
所以我们要还原这个过程将GBK乱码反解成utf-8的原始字节,再将utf-8格式转成unicode,就能正确在VC中 messagebox了
其实事情并不是这样的简单,首先它传回来时并不是以e4b88a 这种utf-8 原始码传回来的,现在我们看到的都是系统平台转换后的,后面我为了捕捉原始码上了代理软件截取了通信的二进制原始信息!它不仅可以返回成功信息,还可以返回错误信息
//下面为上传失败的返回错误信息
涓婁紶澶辫触锛佷紒涓氬敮涓�鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�
//返回的乱码翻译过来:上传失败!企业唯?? 标识码验证不通过??, 正常脑补后修正实际应为"上传失败!企业唯一标识码验证不通过!"
下面我们来分析一下为什么没有正确解码
现在拿出乱码部分 utf-16的 中文显示:涓婁紶澶辫触锛佷紒涓氬敮涓�鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�
00000000h: 93 6D 41 5A 36 7D B6 6F AB 8F E6 89 1B 95 77 4F ; 搈AZ6}秓珡鎵.晈O
00000010h: 12 7D 93 6D 2C 6C 6E 65 93 6D FD FF CD 93 EA 56 ; .}搈,lne搈?蛽闢 //cd93 = 镙
00000020h: 11 76 2E 94 80 4F 59 73 87 74 77 4F 09 7B AB 95 ; .v.攢OYs噒wO.{珪
00000030h: 33 6C 43 7E 1B 95 FD FF ; 3lC~.朂 //FDFF = ?
然后 好巧不巧地 与 UTF-8 格式的 gbk式 解码 高度相似 ,中文为:上传失败!企业唯?? 标识码验证不通过??
00000000h: E4 B8 8A E4 BC A0 E5 A4 B1 E8 B4 A5 EF BC 81 E4 ; 涓婁紶澶辫触锛佷
00000010h: BC 81 E4 B8 9A E5 94 AF E4 B8 20 E6 A0 87 E8 AF ; 紒涓氬敮涓 鏍囪? //??(E4B820)标(e6a087)识(E8AF86)码(E7A081)
00000020h: 86 E7 A0 81 E9 AA 8C E8 AF 81 E4 B8 8D E9 80 9A ; 嗙爜楠岃瘉涓嶉€?
00000030h: E8 BF 87 EF BC 20 ; 杩囷?
通过以上对比,结论是 乱码的GBK编码的16进制就是它的 正确UTF-8格式的字节码,就是说将这些字节按utf-8格式解码就显示出正确的中文了
FDFF,是未能找到映射字符被充的空白占位符,未能被解析,也不能还原,原始码已丢失。 == UTF-8 : EF BF BD
HTTP/1.1 200
Server: nginx/1.26.2
Date: Thu, 23 Apr 2026 08:09:39 GMT
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Connection: close
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><ns1:uploaddevicemanagesoldreturnrecordsResponse xmlns:ns1="DevManage"><ns1:out><?xml version="1.0" encoding="UTF-8"?><result><error>涓婁紶澶辫触锛佷紒涓氬敮涓 鏍囪瘑鐮侀獙璇佷笉閫氳繃锛 </error></result></ns1:out></ns1:uploaddevicemanagesoldreturnrecordsResponse></soap:Body></soap:Envelope>
我们可以看到它内存里返回的字符串信息 soap 包裹着乱码中文 e6 b6 93 就是涓 utf-8的表示
0:000> x
*** WARNING: Unable to verify checksum for C:\WINDOWS\assembly\NativeImages_v4.0.30319_32\System\f291ffc218da543ab4e20e70929af20d\System.ni.dll
0019f358 this = 0x024d26fc
0019f354 request = 0x02631504
0019f350 res = 0x02664034
0019f34c httpWebResponse = 0x02664034
0019f348 memoryStream = 0x02664370
0019f344 responseStream = 0x02663dc0
0019f340 buffer = 0x02664408
0019f33c bytesRead = 0n517
0019f338 strUtf8 = 0x026656ec <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><ns1:uploaddevicemanagesoldreturnrecordsResponse xmlns:ns1="DevManage"><ns1:out><?xml version="1.0" encoding="UTF-8"?><result><error>涓婁紶澶辫触锛佷紒涓氬敮涓�鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�</error></result></ns1:out></ns1:uploaddevicemanagesoldreturnrecordsResponse></soap:Body></soap:Envelope>
0019f334 CS$1$0000 = 0x00000000
0019f330 CS$4$0001 = true
db 0x02664408 L1000
02664408 40 5c 70 6d 00 10 00 00-3c 73 6f 61 70 3a 45 6e @\pm....<soap:En
02664418 76 65 6c 6f 70 65 20 78-6d 6c 6e 73 3a 73 6f 61 velope xmlns:soa
02664428 70 3d 22 68 74 74 70 3a-2f 2f 73 63 68 65 6d 61 p="http://schema
02664438 73 2e 78 6d 6c 73 6f 61-70 2e 6f 72 67 2f 73 6f s.xmlsoap.org/so
02664448 61 70 2f 65 6e 76 65 6c-6f 70 65 2f 22 20 78 6d ap/envelope/" xm
02664458 6c 6e 73 3a 78 73 64 3d-22 68 74 74 70 3a 2f 2f lns:xsd="http://
02664468 77 77 77 2e 77 33 2e 6f-72 67 2f 32 30 30 31 2f www.w3.org/2001/
02664478 58 4d 4c 53 63 68 65 6d-61 22 20 78 6d 6c 6e 73 XMLSchema" xmlns
02664488 3a 78 73 69 3d 22 68 74-74 70 3a 2f 2f 77 77 77 :xsi="http://www
02664498 2e 77 33 2e 6f 72 67 2f-32 30 30 31 2f 58 4d 4c .w3.org/2001/XML
026644a8 53 63 68 65 6d 61 2d 69-6e 73 74 61 6e 63 65 22 Schema-instance"
026644b8 3e 3c 73 6f 61 70 3a 42-6f 64 79 3e 3c 6e 73 31 ><soap:Body><ns1
026644c8 3a 75 70 6c 6f 61 64 64-65 76 69 63 65 6d 61 6e :uploaddeviceman
026644d8 61 67 65 73 6f 6c 64 72-65 74 75 72 6e 72 65 63 agesoldreturnrec
026644e8 6f 72 64 73 52 65 73 70-6f 6e 73 65 20 78 6d 6c ordsResponse xml
026644f8 6e 73 3a 6e 73 31 3d 22-44 65 76 4d 61 6e 61 67 ns:ns1="DevManag
02664508 65 22 3e 3c 6e 73 31 3a-6f 75 74 3e 26 6c 74 3b e"><ns1:out><
02664518 3f 78 6d 6c 20 76 65 72-73 69 6f 6e 3d 22 31 2e ?xml version="1.
02664528 30 22 20 65 6e 63 6f 64-69 6e 67 3d 22 55 54 46 0" encoding="UTF
02664538 2d 38 22 3f 3e 26 6c 74-3b 72 65 73 75 6c 74 3e -8"?><result>
02664548 26 6c 74 3b 65 72 72 6f-72 3e e6 b6 93 e5 a9 81 <error>......
02664558 e7 b4 b6 e6 be b6 e8 be-ab e8 a7 a6 e9 94 9b e4 ................
02664568 bd b7 e7 b4 92 e6 b6 93-e6 b0 ac e6 95 ae e6 b6 ................
02664578 93 ef bf bd e9 8f 8d e5-9b aa e7 98 91 e9 90 ae ................
02664588 e4 be 80 e7 8d 99 e7 92-87 e4 bd b7 e7 ac 89 e9 ................
02664598 96 ab e6 b0 b3 e7 b9 83-e9 94 9b ef bf bd 26 6c ..............&l
026645a8 74 3b 2f 65 72 72 6f 72-3e 26 6c 74 3b 2f 72 65 t;/error></re
026645b8 73 75 6c 74 3e 3c 2f 6e-73 31 3a 6f 75 74 3e 3c sult></ns1:out><
026645c8 2f 6e 73 31 3a 75 70 6c-6f 61 64 64 65 76 69 63 /ns1:uploaddevic
026645d8 65 6d 61 6e 61 67 65 73-6f 6c 64 72 65 74 75 72 emanagesoldretur
026645e8 6e 72 65 63 6f 72 64 73-52 65 73 70 6f 6e 73 65 nrecordsResponse
026645f8 3e 3c 2f 73 6f 61 70 3a-42 6f 64 79 3e 3c 2f 73 ></soap:Body></s
02664608 6f 61 70 3a 45 6e 76 65-6c 6f 70 65 3e 00 00 00 oap:Envelope>
我为了看着方便,简单对照了一下
UTF-8 涓:E6 B6 93, GBK 涓: E4 B8
UTF-8 婁:E5 9A 81, GBK 婁: 8A E4
UTF-8 紶:E7 B4 B6, GBK 紶: BC A0
UTF-8 上:E4 B8 8A 传:E4 BC A0
并用 wingate 通信代理截取通信内容是否为原始信息
00041860h: 55 54 46 2D 38 0D 0A 54 72 61 6E 73 66 65 72 2D ; UTF-8..Transfer-
00041870h: 45 6E 63 6F 64 69 6E 67 3A 20 63 68 75 6E 6B 65 ; Encoding: chunke
00041880h: 64 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 63 ; d..Connection: c
00041890h: 6C 6F 73 65 0D 0A 0D 0A 32 30 35 0D 0A 3C 73 6F ; lose....205..<so
000418a0h: 61 70 3A 45 6E 76 65 6C 6F 70 65 20 78 6D 6C 6E ; ap:Envelope xmln
000418b0h: 73 3A 73 6F 61 70 3D 22 68 74 74 70 3A 2F 2F 73 ; s:soap="http://s
000418c0h: 63 68 65 6D 61 73 2E 78 6D 6C 73 6F 61 70 2E 6F ; chemas.xmlsoap.o
000418d0h: 72 67 2F 73 6F 61 70 2F 65 6E 76 65 6C 6F 70 65 ; rg/soap/envelope
000418e0h: 2F 22 20 78 6D 6C 6E 73 3A 78 73 64 3D 22 68 74 ; /" xmlns:xsd="ht
000418f0h: 74 70 3A 2F 2F 77 77 77 2E 77 33 2E 6F 72 67 2F ; tp://www.w3.org/
00041900h: 32 30 30 31 2F 58 4D 4C 53 63 68 65 6D 61 22 20 ; 2001/XMLSchema"
00041910h: 78 6D 6C 6E 73 3A 78 73 69 3D 22 68 74 74 70 3A ; xmlns:xsi="http:
00041920h: 2F 2F 77 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30 ; //www.w3.org/200
00041930h: 31 2F 58 4D 4C 53 63 68 65 6D 61 2D 69 6E 73 74 ; 1/XMLSchema-inst
00041940h: 61 6E 63 65 22 3E 3C 73 6F 61 70 3A 42 6F 64 79 ; ance"><soap:Body
00041950h: 3E 3C 6E 73 31 3A 75 70 6C 6F 61 64 64 65 76 69 ; ><ns1:uploaddevi
00041960h: 63 65 6D 61 6E 61 67 65 73 6F 6C 64 72 65 74 75 ; cemanagesoldretu
00041970h: 72 6E 72 65 63 6F 72 64 73 52 65 73 70 6F 6E 73 ; rnrecordsRespons
00041980h: 65 20 78 6D 6C 6E 73 3A 6E 73 31 3D 22 44 65 76 ; e xmlns:ns1="Dev
00041990h: 4D 61 6E 61 67 65 22 3E 3C 6E 73 31 3A 6F 75 74 ; Manage"><ns1:out
000419a0h: 3E 26 6C 74 3B 3F 78 6D 6C 20 76 65 72 73 69 6F ; ><?xml versio
000419b0h: 6E 3D 22 31 2E 30 22 20 65 6E 63 6F 64 69 6E 67 ; n="1.0" encoding
000419c0h: 3D 22 55 54 46 2D 38 22 3F 3E 26 6C 74 3B 72 65 ; ="UTF-8"?><re
000419d0h: 73 75 6C 74 3E 26 6C 74 3B 65 72 72 6F 72 3E E6 ; sult><error>?
000419e0h: B6 93 E5 A9 81 E7 B4 B6 E6 BE B6 E8 BE AB E8 A7 ; 稉濠佺炊婢惰精瑙
000419f0h: A6 E9 94 9B E4 BD B7 E7 B4 92 E6 B6 93 E6 B0 AC ; ﹂敍浣风磼娑撴艾
00041a00h: E6 95 AE E6 B6 93 EF BF BD E9 8F 8D E5 9B AA E7 ; 鏁稉锟介弽鍥
00041a10h: 98 91 E9 90 AE E4 BE 80 E7 8D 99 E7 92 87 E4 BD ; 槕閻線鐛欑拠浣
00041a20h: B7 E7 AC 89 E9 96 AB E6 B0 B3 E7 B9 83 E9 94 9B ; 风瑝闁俺绻冮敍
00041a30h: EF BF BD 26 6C 74 3B 2F 65 72 72 6F 72 3E 26 6C ; 锟?lt;/error>&l
00041a40h: 74 3B 2F 72 65 73 75 6C 74 3E 3C 2F 6E 73 31 3A ; t;/result></ns1:
00041a50h: 6F 75 74 3E 3C 2F 6E 73 31 3A 75 70 6C 6F 61 64 ; out></ns1:upload
00041a60h: 64 65 76 69 63 65 6D 61 6E 61 67 65 73 6F 6C 64 ; devicemanagesold
00041a70h: 72 65 74 75 72 6E 72 65 63 6F 72 64 73 52 65 73 ; returnrecordsRes
00041a80h: 70 6F 6E 73 65 3E 3C 2F 73 6F 61 70 3A 42 6F 64 ; ponse></soap:Bod
00041a90h: 79 3E 3C 2F 73 6F 61 70 3A 45 6E 76 65 6C 6F 70 ; y></soap:Envelop
00041aa0h: 65 3E ; e>
HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.9044)
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: 222.185.127.216:7003
Content-Length: 609
Expect: 100-continue
Connection: Keep-Alive
到目前为止,我们认为它是 将utf-8的文字gbk编码了一次,又再utf-8的输出给客户端,当时我就想用java来还原这个过程,看看我猜的对不对
但是我是在android手机的java环境测试的 ,代码如下
结果并没有返回我期望的"上传失败!企业唯?? 标识码验证不通过??"
而是"上传失败!企业唯一标识码验证不通过�?"
package com.bosd.javatest;
..//忽略
public class MainActivity extends AppCompatActivity
{
private AppBarConfiguration appBarConfiguration;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
String correctMessage = null;
try
{
correctMessage = "上传失败!企业唯一标识码验证不通过!";
}
catch (Exception e)
{
}
System.out.println("1. 正确的原始消息: " + correctMessage);
byte[] wrongGbkBytes = new byte[0]; // 获取正确的 UTF-8 字节
try
{
wrongGbkBytes = correctMessage.getBytes("utf-8");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
System.out.println("Original UTF-8 Hex");
printHex(wrongGbkBytes);
String corruptedString = null;
try
{
corruptedString = new String(wrongGbkBytes,"GBK");
System.out.println("After GBK Encode Utf-8 Hex");
printHex(corruptedString.getBytes("gbk"));
}
catch (Exception e)
{
}
System.out.println("2. 服务端错误解读后产生的乱码字符串: " + corruptedString);
byte[] finalBytesSent = new byte[0];
try
{
finalBytesSent = corruptedString.getBytes("utf-8");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
System.out.println("3. 最终发送给客户端的 UTF-8 字节 (十六进制): ");
printHex(finalBytesSent);
String whatClientSees = null;
try
{
whatClientSees = new String(finalBytesSent, "utf-8");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
System.out.println("4. 客户端最终看到的内容: " + whatClientSees);
byte[] restoredUtf8Bytes = new byte[0];
try
{
restoredUtf8Bytes = whatClientSees.getBytes("GBK");
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
String fixedMessage = new String(restoredUtf8Bytes, StandardCharsets.UTF_8);
System.out.println("5. 修复后的消息: " + fixedMessage);
try
{
testprinthex();
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
}private static void printHex(byte[] bytes)
{
for (byte b : bytes) {
System.out.printf("%02X ", b);
}
System.out.println();
}
}
}
1. 正确的原始消息: 上传失败!企业唯一标识码验证不通过!
2026-04-28 15:15:39.989 29708-29708 System.out com.bosd.javatest I Original UTF-8 Hex
2026-04-28 15:15:39.993 29708-29708 System.out com.bosd.javatest I E4 B8 8A E4 BC A0 E5 A4 B1 E8 B4 A5 EF BC 81 E4 BC 81 E4 B8 9A E5 94 AF E4 B8 80 E6 A0 87 E8 AF 86 E7 A0 81 E9 AA 8C E8 AF 81 E4 B8 8D E9 80 9A E8 BF 87 EF BC 81
2026-04-28 15:15:39.995 29708-29708 System.out com.bosd.javatest I After GBK Encode Utf-8 Hex
2026-04-28 15:15:40.000 29708-29708 System.out com.bosd.javatest I E4 B8 8A E4 BC A0 E5 A4 B1 E8 B4 A5 EF BC 81 E4 BC 81 E4 B8 9A E5 94 AF E4 B8 80 E6 A0 87 E8 AF 86 E7 A0 81 E9 AA 8C E8 AF 81 E4 B8 8D E9 80 9A E8 BF 87 EF BC 3F
2026-04-28 15:15:42.102 29708-29708 System.out com.bosd.javatest I €涓?
2026-04-28 15:15:43.054 29708-29708 System.out com.bosd.javatest I 2. 服务端错误解读后产生的乱码字符串: 涓婁紶澶辫触锛佷紒涓氬敮涓€鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�
2026-04-28 15:15:43.054 29708-29708 System.out com.bosd.javatest I 3. 最终发送给客户端的 UTF-8 字节 (十六进制):
2026-04-28 15:15:43.062 29708-29708 System.out com.bosd.javatest I E6 B6 93 E5 A9 81 E7 B4 B6 E6 BE B6 E8 BE AB E8 A7 A6 E9 94 9B E4 BD B7 E7 B4 92 E6 B6 93 E6 B0 AC E6 95 AE E6 B6 93 E2 82 AC E9 8F 8D E5 9B AA E7 98 91 E9 90 AE E4 BE 80 E7 8D 99 E7 92 87 E4 BD B7 E7 AC 89 E9 96 AB E6 B0 B3 E7 B9 83 E9 94 9B EF BF BD
2026-04-28 15:15:43.063 29708-29708 System.out com.bosd.javatest I 4. 客户端最终看到的内容: 涓婁紶澶辫触锛佷紒涓氬敮涓€鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�
2026-04-28 15:15:43.065 29708-29708 System.out com.bosd.javatest I 5. 修复后的消息: 上传失败!企业唯一标识码验证不通过�?
2026-04-28 15:15:43.069 29708-29708 System.out com.bosd.javatest I 构造的字节序列: E6 B6 93 E5 A9 81 E7 B4 B6 E6 BE B6 E8 BE AB E8
2026-04-28 15:15:43.071 29708-29708 System.out com.bosd.javatest I A7 A6 E9 94 9B E4 BD B7 E7 B4 92 E6 B6 93 E6 B0
2026-04-28 15:15:43.073 29708-29708 System.out com.bosd.javatest I AC E6 95 AE E9 94 9F E8 8A A5 E7 88 A3 E7 92 87
2026-04-28 15:15:43.075 29708-29708 System.out com.bosd.javatest I E5 97 99 E7 88 9C E6 A5 A0 E5 B2 83 E7 98 89 E6
2026-04-28 15:15:43.077 29708-29708 System.out com.bosd.javatest I B6 93 E5 B6 89 E2 82 AC E6 B0 B3 E7 B9 83 E9 94
2026-04-28 15:15:43.078 29708-29708 System.out com.bosd.javatest I 9B EF BF BD
此时事件并没有结束,我们只是证明了它用GBK重新编码了UTF-8的中文,最后又把它转成UTF-8输出给客户端,并没有完全实现,好比是确定某人是杀人凶手,却没有发现作案工具,你说是刀口所至命的,那是什么刀,小李飞刀还是金丝大环刀呢? 无法在卷宗上结案啊,需要继续探究。
因为你会发现从信息"上传失败!企业唯一标识码验证不通过! " 到 "上传失败!企业唯??标识码验证不通过??" 没有一个完整性论证
我的JAVA代码在中文还原时输出的是 "上传失败!企业唯一标识码验证不通过�?",用了许多方式来调试来调整字符串的拼接也没用,好气啊
每天都在脑中重复这个过程,我试着在头脑中解析这个GBK编码的方式,直觉一直告诉我我的方法没有问题测试也没有问题但返回的结果就是不对
返复在脑海里重现 解析 "一"字的 UTF-8编码(E4 B8 80),E4 B8 用GBK来读就是涓, 0x80,GBK没有映射就应该是0xEFBFBD 替换符
涓的UTF-8字节码(E6 B6 93)但Win java 这里却返回了 欧元符号€,经过反复的思考后我觉得应该是Windows系统的问题,然后我就找到原生Linux Java 平台再次运行我同样的JAVA代码,结果不出所料的与我期望的结果一至了,我得到了如下输出:
1. 正确的原始消息: 上传失败!企业唯一标识码验证不通过!
Original UTF-8 Hex
E4 B8 8A E4 BC A0 E5 A4 B1 E8 B4 A5 EF BC 81 E4 BC 81 E4 B8 9A E5 94 AF E4 B8 80 E6 A0 87 E8 AF 86 E7 A0 81 E9 AA 8C E8 AF 81 E4 B8 8D E9 80 9A E8 BF 87 EF BC 81
After GBK Encode Utf-8 Hex
E6 B6 93 E5 A9 81 E7 B4 B6 E6 BE B6 E8 BE AB E8 A7 A6 E9 94 9B E4 BD B7 E7 B4 92 E6 B6 93 E6 B0 AC E6 95 AE E6 B6 93 EF BF BD E9 8F 8D E5 9B AA E7 98 91 E9 90 AE E4 BE 80 E7 8D 99 E7 92 87 E4 BD B7 E7 AC 89 E9 96 AB E6 B0 B3 E7 B9 83 E9 94 9B EF BF BD
2. 服务端错误解读后产生的乱码字符串: 涓婁紶澶辫触锛佷紒涓氬敮涓�鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�
3. 最终发送给客户端的 UTF-8 字节 (十六进制):
E6 B6 93 E5 A9 81 E7 B4 B6 E6 BE B6 E8 BE AB E8 A7 A6 E9 94 9B E4 BD B7 E7 B4 92 E6 B6 93 E6 B0 AC E6 95 AE E6 B6 93 EF BF BD E9 8F 8D E5 9B AA E7 98 91 E9 90 AE E4 BE 80 E7 8D 99 E7 92 87 E4 BD B7 E7 AC 89 E9 96 AB E6 B0 B3 E7 B9 83 E9 94 9B EF BF BD
4. 客户端最终看到的内容: 涓婁紶澶辫触锛佷紒涓氬敮涓�鏍囪瘑鐮侀獙璇佷笉閫氳繃锛�
这个结果让我觉得Windows 平台中GBK 编码中有微软自已的实现与扩充,比如对于 80 就被映射到了€符号.... 标准JAVA GBK编码并没有这个设定,它直接变成不可识别的标志字符串"EFBFBD", 所以Webservice的平台是非Windows系统的java 标准 GBK 编码实现的,真相大白了。
这个编码策略的底层平台实现差异违背了 Java (WORA,Write Once, Run Anywhere)一次编写随处运行的理念,微软画蛇添足。
但是....第二天我时而翻来复去地在脑海里复现这个过程,想来想去发现一个细思极恐的问题,我的测试方法好像有问题,因为我是在Android手机上运行的程序,并没有在windows本身中运行java,那么我的结论还正确吗?
于是我又在Win 10上用命令行 编译了这段代码,并在命令行中运行结果与上面是一至的,是我错怪了Windows 冤枉了好人啊!于是再用GB18030(国标,严格的GBK标准)在手机上运行了一次,这回的结果是对的了, 说明是Android手机上的GBK有私自扩展将拉丁字符0x80映射过来了,可但是, windows api /.net 原生app调用GBK编码的结果同样是被映射的,它执行的CodePage936扩展行为,也不算冤枉。
//下面为android手机中的gbk解码器描述,手机兼容了 cp936的行为。
corruptedString = new String(wrongGbkBytes,"gbk");
this = {CharsetICU@5219}
icuCanonicalName = "windows-936-2000" 这是android手机中的编码器名子
aliasSet = {Collections$UnmodifiableSet@5223}
aliases = [GBK, iso-ir-58, csISO58GB231280, csGB2312, chinese, MS936, GB_2312-80, GB2312, windows-936, CP936]
GBK解码时是按双字节读取中文,但utf-8是三字节表示中文,所以反复编解码会产生字节丢失变成了\uFFFD,就不能还原成原来的中文了。
这是服务端的webservice错误编码中文所至,所以我们客户端现在只能提示"上传失败!企业唯??标识码验证不通过??" ,哦不, 我们手动替换一下吧 手动把错误信息修正.