У меня есть потребительское приложение, которое использует IBMMQ для получения сообщений от администратора очередей. Я не контролирую издателя, только потребителя. Вот часть кода для моего потребителя:
while(true) {
message = (TextMessage) queueReceiver.receive(200);
if (message != null) {
messageFile = messageTypeToListenerMapping.get(type).generateMessageNameAndWriteToDisk(message.getText(), source, saveDirectory);
} else {
break;
}
Этот код отлично работает и может получать сообщение как TextMessage
объект почти для всех моих очередей, кроме одной. Когда приложение пытается получить сообщение из этой очереди, я получаю эту ошибку:
2021-10-05 22:12:31.831 DEBUG 30050 --- [nio-8181-exec-8] o.s.web.servlet.DispatcherServlet : GET "/retrieveAllMessagesFromQueue", parameters={}
2021-10-05 22:12:31.832 DEBUG 30050 --- [nio-8181-exec-8] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>>> ,
2021-10-05 22:12:36.882 DEBUG 30050 --- [nio-8181-exec-8] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public Exception.ApiErrorResponse Octopus.controller.OctopusRestController.handleJmsException(javax.jms.JMSException)
2021-10-05 22:12:36.899 DEBUG 30050 --- [nio-8181-exec-8] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
2021-10-05 22:12:36.899 DEBUG 30050 --- [nio-8181-exec-8] m.m.a.RequestResponseBodyMethodProcessor : Writing [[email protected]]
2021-10-05 22:12:36.900 DEBUG 30050 --- [nio-8181-exec-8] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [com.ibm.msg.client.jms.DetailedJMSException: JMSCMQ1049: The character set '1208(UTF-8) Unmappable Action: REPORT, Unmappable Replacement: 63, spaceByte: 32' cannot convert some or all of the string '[[email protected]'
An attempt was made to send or receive string data using a character set not capable of translating the strings content.
Only encode a message using a character set known to be appropriate for the string data being transmitted.]
2021-10-05 22:12:36.901 DEBUG 30050 --- [nio-8181-exec-8] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
После некоторой отладки я обнаружил, что ошибка возникает при выполнении этого кода: message.getText()
Я считаю, что, возможно, сообщение, помещаемое издателем в очередь, содержит какие-то специальные символы, которые приложение не может обработать. Поэтому я попытался посмотреть, смогу ли я использовать сообщение для этой конкретной очереди, используя BytesMessage
вместо этого. Вот код ниже:
BytesMessage byteMessage;
byteMessage = (BytesMessage) queueReceiver.receive(200);
int TEXT_LENGTH = new Long(byteMessage.getBodyLength()).intValue();
byte[] text_bytes = new byte[TEXT_LENGTH];
byteMessage.readBytes(text_bytes, TEXT_LENGTH);
String codePage = byteMessage.getStringProperty(WMQConstants.JMS_IBM_CHARACTER_SET);
String textString = new String(text_bytes, codePage);
if (textString != null) {
messageFile = messageTypeToListenerMapping.get(type).generateMessageNameAndWriteToDisk(textString, source, saveDirectory)
} else {
break;
}
Однако я сталкиваюсь с этой ошибкой:
2021-10-27 22:29:34.046 DEBUG 20987 --- [nio-8181-exec-1] o.s.web.servlet.DispatcherServlet : Failed to complete request: java.lang.ClassCastException: com.ibm.jms.JMSTextMessage cannot be cast to javax.jms.BytesMessage
2021-10-27 22:29:34.053 ERROR 20987 --- [nio-8181-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: com.ibm.jms.JMSTextMessage cannot be cast to javax.jms.BytesMessage] with root cause
java.lang.ClassCastException: com.ibm.jms.JMSTextMessage cannot be cast to javax.jms.BytesMessage
Насколько я понимаю, сообщение не может быть преобразовано из TextMessage
в ByteMessage
, что также означает, что издатель отправил сообщение как TextMessage
. Если издатель отправил сообщение как TextMessage
, то почему я вообще сталкиваюсь с этой проблемой? Я немного смущен всем этим и был бы признателен за некоторые рекомендации.
РЕДАКТИРОВАТЬ: Я amqsbcg
выполнил запрос @MoragHughson, и вот подробности одного из сообщений:
MQGET of message number 14861, CompCode:0 Reason:0
****Message descriptor****
StrucId : 'MD ' Version : 2
Report : 0 MsgType : 8
Expiry : -1 Feedback : 0
Encoding : 546 CodedCharSetId : 1208
Format : 'MQSTR '
Priority : 0 Persistence : 1
MsgId : X'414D5120514D2E44303014D5120514D2E443030A0EF121'
CorrelId : X'000000000000000000000000000000000000000000000000'
BackoutCount : 0
ReplyToQ : ' '
ReplyToQMgr : 'QM.1010101_4642 '
** Identity Context
UserIdentifier : 'user2 '
AccountingToken :
X'0A31303030303639333331639333331639333331004568490000000000000006'
ApplIdentityData : ' '
** Origin Context
PutApplType : '6'
PutApplName : 'mqm_sender '
PutDate : '00000000' PutTime : '00000000'
ApplOriginData : ' '
GroupId : X'000000000000000000000000000000000000000000000000'
MsgSeqNumber : '1'
Offset : '0'
MsgFlags : '0'
OriginalLength : '-1'
**** Message ****
length - 64 of 64 bytes
00000000: 0000 0000 B3DC B059 6400 0000 524D 5320 '.....ܰYd...RMS '
00000010: 2052 3235 3139 3435 3734 3437 3030 3030 ' R25194574470000'
00000020: 3120 2020 2020 2020 2020 2020 2020 2032 '1 2'
00000030: 3032 3131 3032 3231 3431 3333 3730 3020 '021102214133700 '
No more messages
MQCLOSE
Похоже, что CodedCharSetId - 1208, что похоже на UTF-8. Если это так, тогда TextMessages должны работать нормально, если я не ошибаюсь?
amqsbcg
вашей очереди, чтобы вы могли видеть все шестнадцатеричные байты сообщения. Это поможет отладить проблему, вероятно, как вы говорите с недопустимым символом в сообщении. Для запускаamqsbcg
укажите имя очереди в качестве параметра 1 и QMgrName в качестве параметра 2. Если вам нужно работать как клиент, можно использовать переменную среды MQSERVER.amqsbcg
но я немного покопался в коде производителя (который написан на C, не уверен, что это что-то меняет). Я посмотрел на свойства очереди, которые были установлены для этой очереди, и объект MQMD был установлен наMQMD_DEFAULT
. Однако в документации значение по умолчанию для кодировки «зависит от среды». Не уверен, что эта информация полезна, но я свяжусь с вами, как только запущу образец.