公司的项目用到了rocketMQ,看到里面有段这样的代码,生产者生产消息
1 2 3 4 5 6 7
| private static final ObjectMapper OM = new ObjectMapper(); ... Message message = new Message(this.topic, "create", uid.toString(), OM.writeValueAsBytes(uid)); message.setWaitStoreMsgOK(true); SendResult sendResult = producer.send(message, new SelectMessageQueueByHash(), uid); ...
|
消费者的代码是这样的:
1 2 3 4
| ... String body = new String(msg.getBody(), Charset.defaultCharset()); uid = Integer.parseInt(body); ...
|
初看起来没有毛病,而且线上也正常运行,于是我也照葫芦画瓢,写了一个类似的,生产者代码:
1 2 3 4 5
| ... Message msg = new Message(topic, tag, payNo, OM.writeValueAsBytes(payNo)); msg.setWaitStoreMsgOK(true); SendResult sendResult = producer.send(msg, new SelectMessageQueueByHash(), payNo); ...
|
消费者代码如下:
1 2 3 4
| ... String payNo = new String(msg.getBody(), Charset.defaultCharset()); bizSalePayService.callbackPaySystem(payNo); ...
|
结果在调试的时候发现,这个payNo已经不是生产者塞进去的那个值了,很是纳闷,于是写了一段代码测试一下
1 2 3 4 5 6 7 8 9 10 11
| ... String payNo = "{\"uid\":123456}"; ObjectMapper om = new ObjectMapper(); byte[] payNoBytes = om.writeValueAsBytes(payNo); String payNo1 = new String(payNoBytes, Charset.defaultCharset()); if (payNo.equals(payNo1)) { System.out.println("yes"); } else { System.out.println("no"); } ...
|
发现这样输出是no,断点调试发现payNo1的值是”\”{\”uid\”:123456}\””,也就是说,多了一对引号,那么这对引号哪里来的?打个断点看一下jackson的源码实现:
可以看到jackson在转byte的时候在字符串的首尾增加了引号。
到这里大概就知道原因了,可以理解为jackson有一套自己的“协议”,为不同的类型增加了一些字符,所以我们在转回去的时候也需要使用它提供的接口,而不能强行将byte转为String:
1
| String payNo2 = om.readValue(payNoBytes, String.class);
|
这样payNo2和payNo就一模一样了。
总结成一句话就是对不熟悉的类库使用时要慎重。