从服务总线中提取消息时出现异常

时间:2016-11-25 07:33:35

标签: java azure servicebus jsm

我想从服务总线中提取消息。消息只不过是XML。 我想使用PEEK_LOCK选项来实现目标。

目前,队列中没有消息。我的代码每30秒执行一次计划。如果队列中有任何消息,它将提取消息,否则将打印不再消息

ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;
opts.setReceiveMode(ReceiveMode.PEEK_LOCK);
service.getQueue(queueName).getValue().setMaxSizeInMegabytes((long) 1);
BrokeredMessage message;
message = service.receiveQueueMessage(queueName).getValue();
StreamSource source = null;
ResponseEntity<String> response = null;
LOG.debug("Message: " + message);
// LOG.debug("message.getMessageId(): " + message.getMessageId());
// try {
if (message != null) {
    source = new StreamSource(message.getBody());
    StringWriter outWriter = new StringWriter();
    StreamResult result = new StreamResult(outWriter);
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer();
    transformer.transform(source, result);
    StringBuffer sb = outWriter.getBuffer();
    String finalstring = sb.toString();
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    InputSource src = new InputSource();
    src.setCharacterStream(new StringReader(finalstring));

    Document doc = builder.parse(src);
    String ecnNo = doc.getElementsByTagName(xmlECNNoTag).item(0).getTextContent();

    LOG.info(ecnNo + " Is pulled from queue "); 
    if (LOG.isDebugEnabled()) {
        LOG.info("XML Content: " + finalstring);
    }
}
service.deleteMessage(message);

如果我删除了peek_lock代码,我的代码就可以了。使用peek_lock我收到此错误:

  

javax.xml.transform.TransformerException中:   org.xml.sax.SAXParseException; lineNumber:1; columnNumber:50;白色   publicId和systemId之间需要空格。在   com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:749)   〜[na:1.8.0_66] at   com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:351)   〜[na:1.8.0_66] at   com.jci.subscriber.service.PLMSubscriberMSServiceImpl.azureMessageSubscriber(PLMSubscriberMSServiceImpl.java:160)   〜[classes /:na] at   com.jci.subscriber.PLMSubscriberMSApplication.getXML(PLMSubscriberMSApplication.java:118)   [classes /:na] at sun.reflect.GeneratedMethodAccessor101.invoke(未知   来源)〜[na:na] at   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)   〜[na:1.8.0_66] at java.lang.reflect.Method.invoke(Method.java:497)   〜[na:1.8.0_66] at   org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)   [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] at   org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)   [spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] at   java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)   [na:1.8.0_66] at   java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)   [na:1.8.0_66] at   java.util.concurrent.ScheduledThreadPoolExecutor中的$ ScheduledFutureTask.access $ 301(ScheduledThreadPoolExecutor.java:180)   [na:1.8.0_66] at   java.util.concurrent.ScheduledThreadPoolExecutor中的$ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)   [na:1.8.0_66] at   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)   [na:1.8.0_66] at   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:617)   [na:1.8.0_66] at java.lang.Thread.run(Thread.java:745)[na:1.8.0_66]   引起:org.xml.sax.SAXParseException:需要空格   在publicId和systemId之间。在   com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1239)   〜[na:1.8.0_66] at   com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:641)   〜[na:1.8.0_66] at   com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:737)   〜[na:1.8.0_66] ...省略了15个常用帧

1 个答案:

答案 0 :(得分:0)

根据我的经验,根据我的经验,我认为问题是由peek_lock模式通过DocumentBuilder验证来自服务总线的消息的远程DTD架构引起的。

下面有一些解决方法。

  1. 尝试使用方法[DocumentBuilderFactory.setValidating(boolean validating)] 1来停用验证消息,如下所示。

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(false);
    DocumentBuilder builder = factory.newDocumentBuilder();
    
  2. 尝试通过方法DocumentBuilder.setEntityResolver(EntityResolver er)EntityResolver设置自定义DocumentBuilder对象,请参阅SO帖子Make DocumentBuilder.parse ignore DTD references的anwser。

  3.   

    builder.setEntityResolver(new EntityResolver() { @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if (systemId.contains("foo.dtd")) { return new InputSource(new StringReader("")); } else { return null; } } });

    1. 尝试使用dom4j之类的第三方库来解析消息。
    2. 希望它有所帮助。如有任何疑虑,请随时告诉我。