繁体   English   中英

如何仅从特定类型的JMS队列中手动获取消息并保留所有其他消息?

[英]How do I manually get a message from a JMS Queue only of a specific type and leave all other messages?

我有一个队列,其中包含消息,它们都是围绕所有扩展MyCustomMessage不同消息类型(例如MyClientMessageMyInternalMessage包装的ObjectMessage 我要执行以下操作:

  1. 客户端登录系统
  2. 手动查找其中message.getObject()将返回MyClientMessage任何消息
  3. 如果消息属于该类型,但clientId不是已登录用户的消息,则将其放回消息队列中

我该怎么做?

Connection connection = null;
Session session = null;
try {
    connection = factory.createConnection();
    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

    //Get a consumer
    MessageConsumer consumer = session.createConsumer( myQueue );

    //Start the connection
    connection.start();

    //Try to read a message
    Message response = consumer.receive(QUALITY_OF_SERVICE_THRESHOLD_MS);

    //Is anything like this possible?
    ObjectMessage<T> objMessage = ( ObjectMessage<T> ) response;

    //How check object is right type? Only this?
    if ( !objMessage.isBodyAssignableTo( typeClass ) )
    {
        //put back in queue? Or does it stay there until acknowledge?

    }

    //It's the right type
    else
    {
        objMessage.acknowledge();
    }


} finally {
    if (connection != null) {
        connection.close();
    }
}

您可以使用“ JMS消息选择器 ”(最好是为此阅读JMS规范第3.8节,或者您也可以在此处阅读一些说明,或从理论上阅读说明)。 基本上,JMS消息选择器使JMS提供程序可以筛选和发送仅JMS使用者感兴趣的消息,而不发送JMS提供程序收到的所有消息。

因此,它像这样:

  • 消息生产者将产生具有某些特定属性的消息以启用消息选择。
  • 消息使用者将创建一个指定消息选择条件的使用者。
  • 在向该使用者传递消息之前,JMS提供者将检查是否满足该使用者指定的消息选择标准,如果不满足,则它将不会将该特定消息传递给该特定使用者。

在生产者端,您可以指定string属性,如下所示,这只是一个示例,您可以添加对您有意义的string属性。

        Message hellowWorldText = session.createTextMessage("Hello World! " + new Date());
        hellowWorldText.setStringProperty("StockSector", "Technology");

在使用者端,在创建使用者时,您可以指定消息选择条件:

        String selector = new String("(StockSector = 'Technology')");
        MessageConsumer consumer = session.createConsumer(queue, selector);

请注意,您可以指定多个消息选择属性/条件,因此您可以根据需要添加多个条件,可以将它们分组为一个条件,也可以添加单独的条件。

下面是完整的工作代码示例,您只需要确保生产者和使用者的选择器匹配即可,因此在生产者中,您不能使用当前日期/时间戳之类的消息作为消息选择属性,因为在消费者方面您无法指定相同的内容。

JmsProducerQueueClient:

import java.util.Date;
import java.util.Hashtable;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JmsProducerQueueClient {
    public static void main(String[] args) throws NamingException, JMSException {
        Connection connection = null;
        try {
            Context context = getInitialContext();
            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("ConnectionFactory2");
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
            Queue queue = (Queue) context.lookup("Queue0");
            connection.start();
            MessageProducer producer = session.createProducer(queue);
            Message hellowWorldText = session.createTextMessage("Hello World! " + new Date());
            hellowWorldText.setStringProperty("StockSector", "Finance");
            producer.send(hellowWorldText);
        } finally {
            if (connection != null) {
                connection.close();
            }
        }

    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Context getInitialContext() throws NamingException {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
        env.put(Context.PROVIDER_URL, "t3://localhost:8208");
        Context context = new InitialContext(env);
        return context;
    }
}

JmsConsumerQueueClient:

import java.util.Hashtable;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JmsConsumerQueueClient {
    public static void main(String[] args) throws NamingException, JMSException {
        Connection connection = null;
        try {
            Context context = getInitialContext();
            ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("ConnectionFactory1");
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
            Queue queue = (Queue) context.lookup("Queue0");
            String selector = new String("(StockSector = 'Technology')");
            MessageConsumer consumer = session.createConsumer(queue, selector);
            connection.start();
            TextMessage hellowWorldText = (TextMessage) consumer.receive();

            System.out.println("> " + hellowWorldText + " | " + hellowWorldText.getText());

        } finally {
            if (connection != null) {
                connection.close();
            }
        }

    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Context getInitialContext() throws NamingException {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
        env.put(Context.PROVIDER_URL, "t3://localhost:7001");
        Context context = new InitialContext(env);
        return context;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM