我目前正在开发一个应用程序,它需要连接MQ队列,以便在另一个服务中保存队列消息信息。一旦完成,服务将通过MQ队列返回结果消息,并返回给我。
我正在发送一个字符串消息,其中包含类似于以下内容的XML消息:
<?xml version="1.0" encoding="UTF-8"?>
<peticionDemanda>
<subtipo>DEMANDA CONTRATACIÓN</subtipo>
</peticionDemanda>看来MQ没有正确地解码“奥斯卡”字符,"subtipo“字段被保存为”├n“。
我正在"UTF-8“中编码该消息,我被告知用于发送该消息的CCSID为850,而不是1208 (属于UTF-8)。
为了运行MQ管理器,我在客户端模式中使用“pymqi”Python库。这是我用来向队列发送消息并获取响应的MQManager类:
class MQManager:
def __init__(self):
self.queue_manager = config.queue_manager
self.channel = config.channel
self.port = config.port
self.host = config.host
self.conn_info = config.conn_info
self.queue_request_name = config.queue_request_name
self.queue_response_name = config.queue_response_name
cd = pymqi.CD()
cd.ChannelName = self.channel
cd.ConnectionName = self.conn_info
cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
cd.TransportType = pymqi.CMQC.MQXPT_TCP
self.qmgr = pymqi.QueueManager(None)
self.qmgr.connect_with_options(self.queue_manager, opts=pymqi.CMQC.MQCNO_HANDLE_SHARE_NO_BLOCK, cd=cd)
def send_message(self, str_xml_message):
# set message descriptor
request_md = pymqi.MD()
request_md.ReplyToQ = self.queue_response_name
request_md.Format = pymqi.CMQC.MQFMT_STRING
queue_request = pymqi.Queue(self.qmgr, self.queue_request_name)
queue_request.put(str_xml_message.encode("UTF-8"), request_md)
queue_request.close()
# Set up message descriptor for get.
response_md = pymqi.MD()
response_md['CorrelId'] = request_md['MsgId']
gmo = pymqi.GMO()
gmo.Options = pymqi.CMQC.MQGMO_WAIT | pymqi.CMQC.MQGMO_FAIL_IF_QUIESCING
gmo.WaitInterval = 5000 # 5 seconds
queue_response = pymqi.Queue(self.qmgr, self.queue_response_name)
message = queue_response.get_no_rfh2(None, response_md, gmo)
queue_response.close()
return str(message)
def close(self):
self.qmgr.disconnect()我想知道如何定义MQ管理器的CCSID值,并希望解决代码页错配问题。
谢谢!
发布于 2019-09-09 16:06:24
在代码中,为在这一行代码中发送的消息创建一个默认消息描述符:
request_md = pymqi.MD()默认情况下,pymqi (与底层IBM库一样)将消息描述符CodedCharSetId设置为值CMQC.MQCCSI_Q_MGR。
这可以在来源中看到。
['CodedCharSetId', CMQC.MQCCSI_Q_MGR, MQLONG_TYPE],IBMMQV9.0KC页面Reference > Developing applications reference > MQI applications reference > Data types used in the MQI > MQMD - Message descriptor > Fields for MQMD > CodedCharSetId (MQLONG)描述了客户端如何处理这个问题:
对于客户端应用程序,MQCCSI_Q_MGR是根据客户端的地区而不是队列管理器上的位置填写的。
IBM故障排除文档默认情况下,对WebSphere MQ客户端消息使用什么CCSID以稍微不同的方式解释了这一点:
MQ客户端根据运行客户端应用程序的环境设置MQCCSI_Q_MGR值。
基于Windows,我猜想您正在运行的是一个不在美国的Windows(它通常使用八百五十 437)。
您有几个选项可以覆盖这个选项:
MQCCSID设置为所需的值(在您的示例中为1208)。这必须在连接到mq之前设置。IBMMQv9.0KC页面Developing applications > Developing MQI applications with IBM MQ > Writing client procedural applications > Using the MQI in a client application > Choosing client or server CCSID中记录了这一点。
下面的示例适用于Windows:
设置MQCCSID=1208mqclient.ini中,您可以在CHANNELS节下设置CCSID=number。IBMMQv9.0KC页面Configuring > Configuring connections between the server and client > Configuring a client using a configuration file > CHANNELS stanza of the client configuration file中记录了这一点。例如:
频道: CCSID=1208发布于 2019-09-09 23:00:46
您不需要更改队列管理器的CCSID。您的问题是,您的邮件包含UTF-8字符,但您已将其发送到一个信封中,将其描述为包含CCSID 850字符。您只需更新发送消息的信封以正确描述您的内容。
我是IBM MQ专家和'C‘程序员,但不是pymqi程序员,但是,看看pymqi帮助和您的示例,我希望这些都是对代码所需的添加。
# set message descriptor
request_md = pymqi.MD()
request_md.ReplyToQ = self.queue_response_name
request_md.Format = pymqi.CMQC.MQFMT_STRING
request_md.CodedCharSetId = 1208pymqi帮助不包括使用CodedCharSetId的任何示例,但MQMD中的所有pymqi字段似乎都与'C‘API头文件cmqc.h中的拼写和大小写完全相同。
请试试这个,看看它是否能解决你的问题。
https://stackoverflow.com/questions/57857224
复制相似问题