一、问题背景。
我们消费activityMQ消息。解析内容出现了乱码。用的是org.fusesource.mqtt.client.MQTT来接收消息。
直接读取org.fusesource.mqtt.client.Future.await() 方法来获取Message。消息内容是存放在payload的流里面。
我们是直接 转为字符串的形式String msg = new String(message.getPayload());来解析。再转化为JSONObject数据。
打印出来的数据居然有乱码:
二、问题定位
发现这个问题后,我们是先找源数据。发现数据中有中文汉字。
而与getBytes相对的,可以通过new String(byte[], decode)的方式来还原这个"中"字,
三、解决
刚开始用String s_utf8 = new String(message.getPayload(),"UTF-8");进行解析。发现还是一样的乱码。
这只能说明对方消息里的编码格式不是utf-8。也找不到对方来确认这个问题。因为new String(byte[], decode)中,byte[]的编码必须和decode一致才能正常的解析到数据。
后来只能通过打日志分析大法来解决这个问题。三种编码格式都试试"ISO8859-1", "GBK", "UTF-8" 。通过日志排查确认到底是哪种格式的。
日志打印情况为:
最后我们确认这个mq消息为gbk编码格式。
注意:
有时候,为了让中文字符适应某些特殊要求(如httpheader要求其内容必须为iso8859-1编码),
可能会通过将中文字符按照字节方式来编码的情况,如:
String s_iso88591 = newString("中".getBytes("UTF-8"),"ISO8859-1"),这样得到的s_iso8859-1字符串实际是三个在ISO8859-1中的字符,在将这些字符传递到目的地后,目的地程序再通过相反的方式Strings_utf8 = newString(s_iso88591.getBytes("ISO8859-1"),"UTF-8")来得到正确的中文汉字"中",这样就既保证了遵守协议规定、也支持中文。