问题描述
我已经编写了下面的代码来读取IBM MQ中的多个消息
com.ibm.mq.MQQueue defaultLocalQueue;
MQQueueManager qManager=null;
MQEnvironment.hostname = "reese.int.westgroup.com";
MQEnvironment.channel = "CLIENTCONNECTION";
MQEnvironment.port = 1414;
String qMngrStr = "";
qManager = new MQQueueManager(qMngrStr);
int openoptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT | MQC.MQOO_INQUIRE ;
String queueName="COMSERV.SRCHEXT.EVENTS.PUBLISH.QA.Q01";
System.out.println("accessing::"+queueName);
defaultLocalQueue = qManager.accessQueue(queueName,openoptions);
//set transport properties.
System.out.println("set MQ props");
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,MQC.TRANSPORT_MQSERIES_CLIENT);
System.out.println("new Queuemanager");
ArrayList<MQMessage> msg = new ArrayList<MQMessage>();
//MQMessage putMessage = new MQMessage();
//String msg = "hello";
// putMessage.writeUTF(msg);
//specify the message options...
// MQPutMessageOptions pmo = new MQPutMessageOptions();
// accept
// put the message on the queue
//defaultLocalQueue.put(putMessage,pmo);
boolean getMore = true;
while(getMore)
{
MQMessage getMessages= new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options=MQC.MQGMO_WAIT;
gmo.waitInterval=1000000;
//gmo.wait(100000);
System.out.println("get messages::"+gmo.toString());
defaultLocalQueue.get(getMessages,gmo);
msg.add(getMessages);
int length=getMessages.getMessageLength();
System.out.println("length::"+length);
String retrievedMsg = getMessages.readStringOfCharLength(length);
System.out.println("Message got from MQ: "+retrievedMsg);
}
if(defaultLocalQueue.getCurrentDepth()==0)
{
getMore=false;
}
for (MQMessage message : msg)
{
System.out.println("message::"+message);
}
}
行
String retrievedMsg = getMessages.readStringOfCharLength(length);
即使消息在MQ中存在并且消息的长度也在打印3760,也会导致EOF异常。
下面是该异常的完整堆栈跟踪。
length::3760
java.io.EOFException: MQJE086: End of file exception ('MQMessage.readChar()').
at com.ibm.mq.MQMessage.readChar(MQMessage.java:908)
at com.ibm.mq.MQMessage.readStringOfCharLength(MQMessage.java:1232)
at com.tlr.searchextract.messages.MessageTrigger_ABean.init(MessageTrigger_ABean.java:109)
at com.tlr.searchextract.servlet.SEControllerServlet.insertRequestTemplate(SEControllerServlet.java:1385)
at com.tlr.searchextract.servlet.SEControllerServlet.performTask(SEControllerServlet.java:2055)
at com.tlr.searchextract.servlet.SEControllerServlet.doPost(SEControllerServlet.java:117)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:203)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
请帮助我。
解决方法
从MQ KnowLedge Center中的MQMessage:
getMessageLength()获取此消息数据的字节数 消息。
因此,一种方法以字节为单位,然后使用readStringOfCharLength方法以字符为单位。
仅供参考:字节长度!=字符长度
您应该使用readStringOfByteLength方法。
即
int length=getMessages.getMessageLength();
String retrievedMsg = getMessages.readStringOfByteLength(length);
更新时间:2020年8月19日。
如果MQ无法将消息转换为字符串,则可以将其作为字节数组获取,并让JVM尝试将其转换为字符串。
int length=getMessages.getMessageLength();
byte[] bMsg = new byte[length];
getMessages.readFully(bMsg);
String retrievedMsg = new String(bMsg);
,
这在Printing the content of a message using IBM® MQ classes for Java中有记录:
import com.ibm.mq.MQMessage;
import com.ibm.mq.headers.MQHeaderList;
...
MQMessage message = ... // Message received from a queue.
System.out.println (new MQHeaderList (message,true));