##前言
这篇笔记是在遇到问题时一遍解决,一遍分析的。分析是为了让自己思路更加清晰,当与此同时,废话也可能会多一些。
总的来说,这次乱码问题是因为客户端对数据加密处理时涉及到了编码,而服务器端在解密还原时也涉及到了编码。即客户端加密过程中有一个操作是字符串转字节数组,即data.getBytes();
,由于没有指明编码,因此默认使用系统编码。而服务器端在解密过程中,有一个操作是字节数组转字符串,即new String(bytes)
,同样由于没有指明编码,因此默认系统编码。当客户端与服务器端的使用的编码不同,就产生了乱码问题。
下面开始是我遇到问题时的记录。有些分析可能不对,有些分析可能太啰嗦。但是,这就是当时我遇到问题时的一些分析。
##0704 之前说的编码乱码的问题
电子账户接口,在解决了公钥私钥问题后,还存在一个乱码问题。当时以为是传输乱码。就凭直觉认为是传输过程中导致的乱码问题。
然后,昨天早上发现了,是因为客户端和服务器的编码不同,导致的乱码问题。然后也没细想,就坚持认为是因为通过接口传输导致的乱码问题。因为我在本地签名验签时,是不会发生乱码问题的。只有在通过接口传输数据后进行验签的时候,才会发生乱码问题。
一开始以为是因为使用了RequeseBody注解来获取Json数据导致的乱码问题,后面我增加多一个中文参数,接收时发现是不会乱码的。因此就排除了是RequestBody导致的乱码问题。
然后通过logger记录关键信息发现,银联方发送前的数据和我方接口到的密文数据是一毛一样的。这就说明了并不是传输导致的乱码问题。(但是当时并能觉悟,还是卡在传输乱码的问题)
当时还是觉得,是不是因为服务器端和客户端的编码不同,导致传输的过程中出现乱码。就是说在客户端是utf8的,然后传输过去之后,服务器端用gbk去解码,就导致了乱码。因为我用了下面的代码去测试,就更坚信这个观点了:
public static void main(String[] args)throws Exception {
String data = "樟大桥";
System.out.println(new String(data.getBytes(),"GBK"));
}
输出结果是:
妯熷ぇ妗�
这和服务器的乱码是一样的:
验签失败,验签源串(即key1=value1&key2=value2串,看看是不是乱码了)为:
card_expir_dt=2512&cardholder_auth_inf=0AM0010010110000000006妯熷ぇ妗?0
我就觉得是传过来是utf8编码,但是服务器端解码是用gbk的。所以导致的问题。
可是,我又传了一个中文字符,服务器端接收时并打印出来的数据是不会出现乱码的啊。。。(再证实一次。确实不会乱码啊)
这就很郁闷了。。。
这是为什么。。。
为什么我客户端是utf8编码,而服务器是gbk,传过去的数据不会出现乱码???因为我传输的不是字节码,是直接传输字符串,所以不会乱码???但是计算机怎么能识别字符串???传输应该是以字节码传输的啊。
留个坑!!
留个坑!!
留个坑!!
留个坑!!
留个坑!!
##new String时使用了默认编码导致的乱码
传过去的参数和接收到的参数是一样的,因为肯定不是传输过程导致的乱码。
那肯定是服务器端在解析的时候出现的乱码。然后找到出现乱码的这个地方:
try {
desKey = RSAUtils.decryptByPrivateKey(tripleDesKey, HttpServer.myPrivateKey);//用私钥解密
jsonBODYStr = TripleDesUtil.decryptMode(desKey, encodeBODY);
logger.info("通过私钥解密,获取明文的会话秘钥成功。再用会话秘钥对称解密得到BODY,BODY包含body和header");
} catch (Exception e) {
logger.error("用私钥解密,获取明文的会话秘钥出现异常:" + e);
throw new Exception("x001");
}