IBM MQ Web API获取无格式消息报错,求临时解决方案
IBM MQ Web API 消息格式不支持报错的临时解决方案
问题背景
第三方应用向我方IBM MQ队列发送消息时未指定消息格式,导致MQ Web API返回如下错误:
"error": [ { "msgId": "MQWBXXXXX", "action": "Resubmit the request, correcting any issues.", "completionCode": 0, "reasonCode": 0, "type": "rest", "message": "MQWBXXXXX: The received or browsed message type is unsupported by the mqweb server.", "explanation": "The mqweb server successfully received an MQ message, but was of an unsupported message type." } ]
第三方修改代码设置MQSTR格式的周期过长,需快速解决以满足交付期限。
可行解决方案
1. 绕过MQ Web API,直接使用MQ客户端消费消息
MQ Web API本身没有配置项可跳过消息格式校验,但直接使用MQ SDK客户端(Java/.NET/Python等)可以忽略格式字段,直接读取消息体,是最快落地的方案。
Java代码示例:
import com.ibm.mq.*; import java.nio.charset.StandardCharsets; public class MQConsumer { public static void main(String[] args) { try { MQQueueManager qmgr = new MQQueueManager("YOUR_QMGR_NAME"); int openOpts = MQC.MQOO_INPUT_SHARED | MQC.MQOO_FAIL_IF_QUIESCING; MQQueue queue = qmgr.accessQueue("YOUR_QUEUE_NAME", openOpts); MQGetMessageOptions gmo = new MQGetMessageOptions(); gmo.options = MQC.MQGMO_WAIT | MQC.MQGMO_NO_CONVERT; // 关闭自动转换,直接读取原始字节 MQMessage message = new MQMessage(); queue.get(message, gmo); // 直接读取字节数组并转字符串 byte[] body = new byte[message.getMessageLength()]; message.readFully(body); String msgContent = new String(body, StandardCharsets.UTF_8); System.out.println("消息内容:" + msgContent); queue.close(); qmgr.disconnect(); } catch (MQException e) { System.err.println("MQ异常:" + e.getReason()); } catch (Exception e) { e.printStackTrace(); } } }
2. 配置队列入队退出程序,自动修正消息格式
通过编写队列入队退出程序,在消息进入队列时自动将格式字段设置为MQSTR(8字节字符串,补空格),从根源解决格式问题,无需修改第三方代码。
步骤:
- 编写C语言退出程序(MQ官方推荐的退出程序语言):
#include <cmqc.h> #include <string.h> MQDLT EnqueueExit(MQHCONN hConn, MQHOBJ hObj, MQMD *pMsgDesc, MQGMO *pGetMsgOpts, MQPMO *pPutMsgOpts, MQBYTE *pBuffer, MQLONG BufferLength, MQLONG *pDataLength, MQLONG *pCompCode, MQLONG *pReason) { // 检查格式是否非MQSTR,是则替换 if (memcmp(pMsgDesc->Format, MQFMT_STRING, MQ_FORMAT_LENGTH) != 0) { memcpy(pMsgDesc->Format, MQFMT_STRING, MQ_FORMAT_LENGTH); } return MQDLT_CONTINUE; // 让消息正常入队 }
- 编译为共享库(如
mq_format_fix.so或mq_format_fix.dll),部署到队列管理器的退出程序目录(如/var/mqm/exits64/)。 - 通过
runmqsc命令绑定到目标队列:
ALTER QUEUE(YOUR_QUEUE_NAME) ENQUEUEEXIT('mq_format_fix')
3. 临时批量转储并重新发送消息(小批量场景)
如果消息量小且为临时应急,可使用MQ命令行工具将原队列消息取出,重新设置格式后放入临时队列,再用MQ Web API消费临时队列。
操作步骤:
- 创建临时队列:
runmqsc YOUR_QMGR_NAME DEFINE QLOCAL(TEMP_FIXED_QUEUE) END
- 取出原队列消息并保存到文件:
amqsget YOUR_ORIGINAL_QUEUE YOUR_QMGR_NAME > msg_dump.txt
- 将消息重新发送到临时队列(
amqsput默认会设置格式为MQSTR):
amqsput TEMP_FIXED_QUEUE YOUR_QMGR_NAME < msg_dump.txt
- 配置MQ Web API消费
TEMP_FIXED_QUEUE的消息。
方案优先级建议
- 优先选择方案1:无需修改MQ配置,快速开发部署,满足短期交付需求。
- 若必须使用MQ Web API,选择方案2:一次性配置后长期生效,适合持续消息流入场景。
- 方案3仅适合小批量临时应急,不建议高吞吐量场景使用。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

