I'm currently developing an application which needs to connect a MQ Queue in order to have the queue saving message information inside another service. Once it's done, the service returns a result message through the MQ Queue and it is returned to me.
I'm sending a string message that contains a XML message similar to the following one:
<?xml version="1.0" encoding="UTF-8"?>
<peticionDemanda>
<subtipo>DEMANDA CONTRATACIÓN</subtipo>
</peticionDemanda>
It appears that MQ is not decoding properly the "Ó" character and "subtipo" field is being saved as "DEMANDA CONTRATACI├ôN".
I'm encoding the message in "UTF-8" and I've been told that the CCSID I'm using to send the message is 850 instead of 1208 (the one belonging to UTF-8).
To run the MQ manager, I'm using "pymqi" Python library in Client Mode. This is the MQManager class I use to send messages to the queue and get the response:
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()
I wonder how can I define the MQ Manager's CCSID value and hopefully solve the codepage mismatch.
Thank you!
In your code you create a default message descriptor for the message you send in this line of code:
request_md = pymqi.MD()
By default pymqi (like the underlying IBM MQ C libraries) will set the message descriptor CodedCharSetId
to the value CMQC.MQCCSI_Q_MGR
.
This can be seen in the source:
['CodedCharSetId', CMQC.MQCCSI_Q_MGR, MQLONG_TYPE],
The IBM MQ v9.0 KC page Reference > Developing applications reference > MQI applications reference > Data types used in the MQI > MQMD - Message descriptor > Fields for MQMD > CodedCharSetId (MQLONG) describes how the client handles this:
For client applications, MQCCSI_Q_MGR is filled in, based on the locale of the client rather than the one on the queue manager.
The IBM MQ Troubleshooting document What CCSID is used by default for WebSphere MQ client messages explains this in a slightly different way:
A MQ client sets the MQCCSI_Q_MGR value based on the environment in which the client application is running.
Based on the 850 CCSID I would guess you are running on a Windows OS that is not in the United States (which commonly uses CCSID 437).
You have a few options to override this:
You can programmatically override the pymqi MQMD default value like this:
request_md.CodedCharSetId = 1208
Set the env variable MQCCSID
to the value you want (in your case 1208). This must be set before you connect to mq. This is documented in the IBM MQ v9.0 KC page Developing applications > Developing MQI applications with IBM MQ > Writing client procedural applications > Using the MQI in a client application > Choosing client or server CCSID.
The example below is for Windows:
SET MQCCSID=1208
In the mqclient.ini
you can set the CCSID=number
under the CHANNELS
stanza. This is documented in the IBM MQ v9.0 KC page Configuring > Configuring connections between the server and client > Configuring a client using a configuration file > CHANNELS stanza of the client configuration file. For example:
CHANNELS:
CCSID=1208