简体   繁体   中英

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

I have a queue that has messages in it where they're all a wrapped ObjectMessage around different message types that all extend MyCustomMessage , eg MyClientMessage , MyInternalMessage . I want to do the following:

  1. Client logs in to the system
  2. Manually look for any messages where the message.getObject() would return a MyClientMessage
  3. If the message is of that type but the clientId is not that of the logged in user, put it back in the message queue

how would I do this?

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();
    }
}

You can use " JMS message selectors " (best is to read JMS specs section 3.8 for that or you can read some description here as well, or read this for theory). Basically JMS message selector enables a JMS provider to filter and send only messages which JMS consumer is interested into, and doesn't send all the messages JMS provider receives.

So, it goes like this:

  • Message producer will produce a message with some specific property to enable message selection.
  • Message consumer will create a consumer specifying the message selection criteria.
  • Before delivering a message to that consumer, JMS provider will check whether the message selection criteria specified by the consumer is met or not, if not met then it will not deliver that particular message to that particular consumer.

At producer end, you can specify the string property as shown below, this is just an example, you can add a string property which is meaningful to you.

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

At consumer end, while creating the consumer you can specify the message selection criteria:

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

Please note that you can specify more than one message selection property/criteria, so based on your needs you can add as many criteria, either you can group them in a single criteria or you can add separate ones.

Below is the full working code sample, you just need to make sure that your selector of producer and consumer is matching, so in producer you cannot use things like current Date/timestamp as message selection property because at consumer side you cannot specify same.

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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