採用 JNDI 查找 JMS 資源,而非硬編碼 ActiveMQ API,使應用遵循 JMS 規範,可無縫切換消息中間件(HornetQ、RabbitMQ 等)。
Tomcat (JNDI 容器) ←→ JNDI 名稱綁定 ←→ ActiveMQ (JMS Provider) ←→ Web 應用
編輯 $CATALINA_BASE/conf/context.xml,添加連接工廠與隊列定義:
<Resource name="queue/connectionFactory"
auth="Container"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="tcp://localhost:61616"
brokerName="LocalActiveMQBroker" />
<Resource name="queue/queue0"
auth="Container"
type="org.apache.activemq.command.ActiveMQQueue"
description="My Queue"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="TomcatQueue" />
cd $ACTIVEMQ_HOME/bin
./activemq start # Windows: activemq.bat start
訪問 https://localhost:8161/admin 查看隊列狀態(默認用戶/密碼 admin/admin)。

核心 JAR:activemq-all-x.x.x.jar、spring-jms.jar、javax.jms-api.jar、Tomcat 容器提供的 javax.naming、javax.servlet。
@WebServlet("/Send")
public class Send extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter out = resp.getWriter();
try {
InitialContext ctx = new InitialContext();
// JNDI 查找(注意 java:comp/env/ 前綴)
Queue queue = (Queue) ctx.lookup("java:comp/env/queue/queue0");
QueueConnectionFactory factory = (QueueConnectionFactory)
ctx.lookup("java:comp/env/queue/connectionFactory");
// 標準 JMS 流程
QueueConnection conn = factory.createQueueConnection();
QueueSession session = conn.createQueueSession(false, Session.DUPS_OK_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);
sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage msg = session.createTextMessage("Hello World");
sender.send(msg);
out.write("Message Sent: " + msg.getText());
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@WebServlet("/Receive")
public class Receive extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter out = resp.getWriter();
try {
InitialContext ctx = new InitialContext();
Queue queue = (Queue) ctx.lookup("java:comp/env/queue/queue0");
QueueConnectionFactory factory = (QueueConnectionFactory)
ctx.lookup("java:comp/env/queue/connectionFactory");
QueueConnection conn = factory.createQueueConnection();
QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueReceiver receiver = session.createReceiver(queue);
conn.start(); // 必須啟動連接才能接收
TextMessage msg = (TextMessage) receiver.receive(); // 阻塞等待
out.write("Message Received: " + msg.getText());
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/Send → 返回 "Message Sent: Hello World",ActiveMQ 控制台隊列消息數 +1
/Receive → 返回 "Message Received: Hello World",隊列消息被消費消失
java:comp/env/(Java EE 標準)Session.DUPS_OK_ACKNOWLEDGE、消費者 Session.AUTO_ACKNOWLEDGE 確認模式可根據業務調整close(),建議用 try-with-resourcesPooledConnectionFactory)、持久化消息、死信隊列