Java 如何仅从JMS队列中手动获取特定类型的消息,并保留所有其他消息?
我有一个队列,其中包含消息,它们都是围绕不同的消息类型包装的Java 如何仅从JMS队列中手动获取特定类型的消息,并保留所有其他消息?,java,jakarta-ee,jms,Java,Jakarta Ee,Jms,我有一个队列,其中包含消息,它们都是围绕不同的消息类型包装的ObjectMessage,这些消息类型都扩展了MyCustomMessage,例如MyClientMessage,MyInternalMessage。我想做以下工作: 客户端登录到系统 手动查找message.getObject()将返回MyClientMessage 如果消息属于该类型,但clientId不是登录用户的,请将其放回消息队列 我该怎么做 Connection connection = null; Session ses
ObjectMessage
,这些消息类型都扩展了MyCustomMessage
,例如MyClientMessage
,MyInternalMessage
。我想做以下工作:
message.getObject()
将返回MyClientMessage
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();
}
}
Connection=null;
会话=空;
试一试{
connection=factory.createConnection();
会话=connection.createSession(false,session.AUTO_-ACKNOWLEDGE);
//获得消费者
MessageConsumer=session.createConsumer(myQueue);
//启动连接
connection.start();
//试着读一条消息
消息响应=消费者接收(服务质量阈值);
//这样做可能吗?
ObjectMessage objMessage=(ObjectMessage)响应;
//如何检查对象是否为正确类型?仅此?
如果(!objMessage.isBodyAssignableTo(typeClass))
{
//把它放回队列?还是一直排到确认为止?
}
//这是正确的类型
其他的
{
objMessage.acknowledge();
}
}最后{
if(连接!=null){
connection.close();
}
}
您可以使用“JMS消息选择器”(最好是阅读JMS规范第3.8节,或者您也可以阅读一些描述,或者阅读一些理论)。基本上,JMS消息选择器允许JMS提供者只过滤和发送JMS消费者感兴趣的消息,而不发送JMS提供者接收的所有消息
所以,它是这样的:
- 消息生成器将生成具有某些特定属性的消息,以启用消息选择
- 消息使用者将创建指定消息选择条件的使用者
- 在将消息传递给该使用者之前,JMS提供程序将检查该使用者指定的消息选择标准是否满足,如果不满足,则不会将该特定消息传递给该特定使用者
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;
}
}
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;
}
}
JmsConsumerQueueClient:
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;
}
}
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;
}
}
您可以使用“JMS消息选择器”(最好是阅读JMS规范第3.8节,或者您也可以阅读一些描述,或者阅读理论)。基本上,JMS消息选择器允许JMS提供者只过滤和发送JMS消费者感兴趣的消息,而不发送JMS提供者接收的所有消息
所以,它是这样的:
- 消息生成器将生成具有某些特定属性的消息,以启用消息选择
- 消息使用者将创建指定消息选择条件的使用者
- 在将消息传递给该使用者之前,JMS提供程序将检查该使用者指定的消息选择标准是否满足,如果不满足,则不会将该特定消息传递给该特定使用者
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;
}
}
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;
}
}
JmsConsumerQueueClient:
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;
}
}
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;
}
}
谢谢你,有一部分你没有提到:在某些情况下,我如何让我的消费者把它放回队列?(例如,某些客户端尚未准备好与创建
MessageConsumer
)的类进行通信@DonRhummy JMS提供程序将过滤掉消息并仅向消费者传递相关消息,因此JMS消费者没有任何责任进行过滤并将其放回,但是,如果您想这样做,那么您可以始终确认该消息(您刚刚使用的消息),从该消息创建一个新消息,然后将其放回同一队列,或者您可以使用其他队列。根据您的需求,JMS临时队列和JMSReplyTo标头可能对您有用。谢谢,我如何接收队列中的所有消息?我只看到了一种接收一条消息的方法。这不起作用。当我使用选择器创建消费者时(以及使用该字符串属性的原始消息),我没有收到任何消息。@DonRhummy我已使用完整的工作代码更新了我的答案,如果您