Java 如何暂停和恢复JMS消息的异步使用

Java 如何暂停和恢复JMS消息的异步使用,java,jms,activemq,jms-topic,Java,Jms,Activemq,Jms Topic,我正在使用activeMQ构建一个应用程序,其中我有一个生产者和消费者。 在消费者iam中,使用MessageListener异步侦听来自生产者的消息,这是使用名为onMessage(Message Message)的方法完成的。 但是在使用这些消息之前,我想执行一个条件检查,然后使用这些消息。 我不想使用消息的同步消费,因为这将违反我的设计 void initialize() throws JMSException { this.connection = this.

我正在使用activeMQ构建一个应用程序,其中我有一个生产者和消费者。 在消费者iam中,使用MessageListener异步侦听来自生产者的消息,这是使用名为onMessage(Message Message)的方法完成的。 但是在使用这些消息之前,我想执行一个条件检查,然后使用这些消息。 我不想使用消息的同步消费,因为这将违反我的设计

  void initialize() throws JMSException {
            this.connection = this.connectionFactory.createConnection();
            this.connection.start();
            final Session session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            final Destination destination = session.createQueue("testQ");
            this.consumer = session.createConsumer(destination);
            this.consumer.setMessageListener(this);
}
检查此处的条件,如检测互联网连接等

public void onMessage(final Message message) {
        Preconditions.checkNotNull(message);

        if (!(message instanceof TextMessage)) {
            _LOG.error("The message is not of type TextMessage but of type {} so we could not process", message.getClass().getSimpleName());
            throw new IllegalArgumentException("This type '" + message.getClass().getSimpleName() + "' of message could not been handled");
        }

        try {
            final String messageType = message.getStringProperty("messageType");
            Preconditions.checkNotNull(messageType);
            _LOG.info("The MessageType is {}", messageType);

            final String msg = ((TextMessage) message).getText();
            Preconditions.checkNotNull(msg);
            _LOG.debug(msg);

            process(messageType, msg);
        } catch (final JMSException e) {
            _LOG.error("We could not read the message", e);
        }
    }

任何代码示例都很好。

不清楚您为什么要进行检查,因为如果连接出现任何问题,您的应用程序将收到此类错误的通知。您可以为JMS连接设置ExceptionListener,如果连接出现问题,将调用它

如果存在连接问题,则不会调用onMessage

另外,在为消费者设置消息侦听器之后,我将推送connection.start()方法调用。connection.start()调用向消息传递提供程序指示应用程序已准备好接收消息

存在用于暂停/停止邮件传递的connection.stop()。您可以再次发出connection.start()以恢复邮件传递


根据您的回复进行更新

我建议您使用客户端确认模式的会话

final Session session = this.connection.createSession(false, Session.CLIENT_ACKNOWLEDGE)

然后在
onMessage
方法中,如果没有internet连接,则不确认该消息。如果消息未过期,则会再次发送该消息。

不清楚您为什么要进行检查,因为如果连接存在任何问题,则会将此错误通知您的应用程序。您可以为JMS连接设置ExceptionListener,如果连接出现问题,将调用它

如果存在连接问题,则不会调用onMessage

另外,在为消费者设置消息侦听器之后,我将推送connection.start()方法调用。connection.start()调用向消息传递提供程序指示应用程序已准备好接收消息

存在用于暂停/停止邮件传递的connection.stop()。您可以再次发出connection.start()以恢复邮件传递


根据您的回复进行更新

我建议您使用客户端确认模式的会话

final Session session = this.connection.createSession(false, Session.CLIENT_ACKNOWLEDGE)

然后在
onMessage
方法中,如果没有internet连接,则不确认该消息。如果消息未过期,则将再次传递该消息。

在异步消息中,您可以在处理消息之前始终检查条件。一旦您的侦听器代码(即OnMessage方法)接收到JMS消息,您就可以给出进一步的方向。我已经解决了这样一个问题,我想用我的db内容检查JMS消息

通过将urlConnection设置为Web服务url,检查internet连接是否处于活动状态,如下所示:

  public static boolean isReachable(String targetUrl) throws IOException
{
   try {
     HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(
        targetUrl).openConnection();
    httpUrlConnection.setRequestMethod("HEAD");


    int responseCode = httpUrlConnection.getResponseCode();

    return responseCode == HttpURLConnection.HTTP_OK;
} catch (UnknownHostException noInternetConnection)
  {
    return false;
   }
}
然后在onMessage方法中,将该方法调用为

public void onMessage(final Message message) {
    if(isReachable){
    Preconditions.checkNotNull(message);

    if (!(message instanceof TextMessage)) {
        _LOG.error("The message is not of type TextMessage but of type {} so we could not process", message.getClass().getSimpleName());
        throw new IllegalArgumentException("This type '" + message.getClass().getSimpleName() + "' of message could not been handled");
    }

    try {
        final String messageType = message.getStringProperty("messageType");
        Preconditions.checkNotNull(messageType);
        _LOG.info("The MessageType is {}", messageType);

        final String msg = ((TextMessage) message).getText();
        Preconditions.checkNotNull(msg);
        _LOG.debug(msg);

        process(messageType, msg);
    } catch (final JMSException e) {
        _LOG.error("We could not read the message", e);
    }
  }
}

在异步消息传递中,您始终可以在处理消息之前检查条件。一旦您的侦听器代码(即OnMessage方法)接收到JMS消息,您就可以给出进一步的方向。我已经解决了这样一个问题,我想用我的db内容检查JMS消息

通过将urlConnection设置为Web服务url,检查internet连接是否处于活动状态,如下所示:

  public static boolean isReachable(String targetUrl) throws IOException
{
   try {
     HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(
        targetUrl).openConnection();
    httpUrlConnection.setRequestMethod("HEAD");


    int responseCode = httpUrlConnection.getResponseCode();

    return responseCode == HttpURLConnection.HTTP_OK;
} catch (UnknownHostException noInternetConnection)
  {
    return false;
   }
}
然后在onMessage方法中,将该方法调用为

public void onMessage(final Message message) {
    if(isReachable){
    Preconditions.checkNotNull(message);

    if (!(message instanceof TextMessage)) {
        _LOG.error("The message is not of type TextMessage but of type {} so we could not process", message.getClass().getSimpleName());
        throw new IllegalArgumentException("This type '" + message.getClass().getSimpleName() + "' of message could not been handled");
    }

    try {
        final String messageType = message.getStringProperty("messageType");
        Preconditions.checkNotNull(messageType);
        _LOG.info("The MessageType is {}", messageType);

        final String msg = ((TextMessage) message).getText();
        Preconditions.checkNotNull(msg);
        _LOG.debug(msg);

        process(messageType, msg);
    } catch (final JMSException e) {
        _LOG.error("We could not read the message", e);
    }
  }
}

谢谢你的回复。好的,我将描述我的场景。假设我从activemq队列中使用的消息,我想将其发送到Web服务,在发送到Web服务之前,iam会检查internet连接是否存在。如果internet连接不存在,我想暂停使用来自MessageListener的消息,这些消息最终将在activemq中因过期时间而过期(根据我的设计)如果internet连接断开,我会将消息发送到webservice。你能帮我编辑我在上面发布的onMessage代码吗。public void onMessage(最终消息){if(isNetavailable()==false){try{this.connection.stop();}catch(jmsceception e){e.printStackTrace();}}否则如果(isNetavailable()==true){尝试{this.connection.start();}catch(JMSException e1){e1.printStackTrace();}}}}}我的问题是在调用Onmessage中的connection.stop()之后,如果没有internet连接,然后下次调用Onmessage来执行connection.start()public void Onmessage(最终消息){if(isReachable==false){return;}否则,如果您发出connection.stop,则在应用程序调用connection.start之前不会调用onMessage。因此,您需要在onMessage之外调用connection.start。另外,在onMessage方法中调用connection.start也是非法的。感谢您的回复。好的,我将描述我的场景。假设我从activemq队列中使用的消息,我想将其发送到Web服务,在发送到Web服务之前,iam会检查internet连接是否存在。如果internet连接不存在,我想暂停使用来自MessageListener的消息,这些消息最终将在activemq中因过期时间而过期(根据我的设计)如果internet连接断开,我会将消息发送到webservice。你能帮我编辑我在上面发布的onMessage代码吗。public void onMessage(最终消息){if(isNetavailable()==false){try{this.connection.stop();}catch(jmsceception e){e.printStackTrace();}}else如果(isNetavailable()==true){尝试{this.connection.start();}catch(J