Java读取IBM MQ消息时字节转字符串异常问题求助
解决IBM MQ消息读取的编码异常问题
你的问题确实是字节数组转字符串时的编码不匹配导致的,具体来说是IBM MQ消息使用的字符编码和你转换时默认的平台编码不一致,才出现了字符间带空格、复制异常的情况。
问题根源分析
IBM MQ的消息默认会使用特定的字符集(CCSID)来编码,比如常见的UTF-16(CCSID 1200)或者带有空字节的编码格式。你当前直接用new String(bMsg)转换字节数组,这个构造器会使用JVM的平台默认编码(比如UTF-8)来解析字节。如果原消息是双字节编码(比如UTF-16),每个实际字符会被拆成两个字节,其中可能包含空字节(\0),这些空字节在打印时会显示为空格,而且在文本编辑器中会被当成字符串终止符,导致只能复制第一个字符。
解决方法
你可以通过两种方式来修复这个问题:
1. 基于消息的实际字符集转换字节数组
先获取MQ消息自带的字符集ID(CCSID),再用对应的编码来解析字节数组:
// 替换原来的String retrievedmsg = new String(bMsg); int ccsid = getMessages.characterSet; // 根据CCSID获取对应的Java编码名称 String charsetName = com.ibm.mq.constants.MQConstants.lookupCCSID(ccsid); String retrievedmsg = new String(bMsg, charsetName);
2. 使用MQMessage内置的字符串读取方法(更推荐)
IBM MQ的MQMessage类提供了专门的读取字符串的方法,会自动根据消息的字符集来解析,避免手动处理编码的麻烦:
// 替换原来的byte数组读取和String转换步骤 String retrievedmsg = getMessages.readString(getMessages.getMessageLength());
额外代码优化建议
你的循环逻辑还有个小问题:getMore的判断放在了循环外面,这会导致循环一直执行直到MQ的等待超时抛出异常。建议你在循环内判断队列深度,或者捕获MQRC_NO_MSG_AVAILABLE异常来终止循环:
while(getMore) { try { MQMessage getMessages = new MQMessage(); MQGetMessageOptions gmo = new MQGetMessageOptions(); gmo.options=MQC.MQGMO_WAIT | MQC.MQGMO_BROWSE_FIRST; gmo.matchOptions=MQC.MQMO_NONE; gmo.waitInterval=100000; defaultLocalQueue.get(getMessages, gmo); // 这里用上面修复后的方式读取消息 String retrievedmsg = getMessages.readString(getMessages.getMessageLength()); System.out.println("retrievedmsg::"+retrievedmsg); if(!retrievedmsg.isEmpty()) { MessageHandler mh = new MessageHandler(); System.out.println("messagehandler java file:"+retrievedmsg); mh.processMessages(retrievedmsg); } msglist.add(retrievedmsg); System.out.println("msglist::"+msglist.toString()); // 检查队列当前深度,如果为0则终止循环 if(defaultLocalQueue.getCurrentDepth() == 0) { getMore = false; } } catch(MQException e) { // 如果没有可用消息,终止循环 if(e.reasonCode == MQC.MQRC_NO_MSG_AVAILABLE) { getMore = false; } else { e.printStackTrace(); } } catch(Exception e) { e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者C2D
相关产品推荐
相关产品推荐

