这个例子是为了熟悉jms的开发流程。
效果是一个servlet向一个message driven bean(mdb)发送消息。服务器是glassfish3.1。
首先建一些jms的资源,包括connectionfactory和一个queue,这个例子是一个PTP的jms链接。
建连接工厂
启动glassfish-》资源-》jms资源-》链接工厂-》新建
池名称(即jndi名称)起名为:jms/QueueConnectionFactory
资源类型选:javax.jms.QueueConnectionFactory,因为我们需要一个队列链接
保存
再建一个目的资源
jms资源-》目的地资源-》新建
jndi名称:jms/SimpleQueue
物理目的地址:SimpleQueue(不懂派什么用,随便取个名字)
资源类型:javax.jms.Queue
资源建好了,开始建立消息通信的两端,producer和consumer。
建一个servlet做producer
eclipse新建一个动态页面项目,新建一个servlet名为Producer,内容如下:
package com.servlets; import java.io.IOException; import javax.annotation.Resource; import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.QueueConnectionFactory; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class Producer */ @WebServlet("/Producer") public class Producer extends HttpServlet { private static final long serialVersionUID = 1L; //@Resource(lookup = "jms/SimpleQueue") private static Queue queue; //@Resource(lookup = "jms/QueueConnectionFactory") private static QueueConnectionFactory connectionFactory; /** * @see HttpServlet#HttpServlet() */ public Producer() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { InitialContext jndiContext = new InitialContext(); connectionFactory = (QueueConnectionFactory)jndiContext.lookup("jms/QueueConnectionFactory");//get the factory from app server queue = (Queue)jndiContext.lookup("jms/SimpleQueue");//get the destination from app server Connection connection = connectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue); TextMessage message = session.createTextMessage(); message.setText("hello from a servlet******************"); System.out.println("producer in servlet has sent hello"); producer.send(message); connection.close(); } catch (JMSException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NamingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } }
原本这里的两个资源可以通过@Resource来注入的,不过遇到个问题就是@Resource在jdk和glassfish中有两个不同的版本,一个(jee6)有成员lookup一个(j2se)没有,所以要用注入会编译出错,所以只能用老派办法,直接从jndi上下文找资源来初始化成员变量。
servlet功能很简单,向SimpleQueue发送一个字符串。
把项目export为war,然后用glassfish发布。
再建一个mdb做consumer:
eclipse新建EJB项目
新建一个类(eclipse的新建mdb有点不对)
|
jms/SimpleQueue
|
|
jms/SimpleQueue
|
jms/QueueConnectionFactory
|
|
jms/SimpleQueue
|
代码如下:
package com.jms; import javax.ejb.MessageDriven; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; /** * Simle message driven bean. */ @MessageDriven(mappedName = "jms/SimpleQueue") public class SimpleMessageDrivenBean implements MessageListener { /** * Default constructor. */ public SimpleMessageDrivenBean() { } /** * @see MessageListener#onMessage(Message) */ public void onMessage(Message message) { try { System.out.println("Got message: " + ((TextMessage) message).getText() + " @" + System.currentTimeMillis()); } catch (JMSException e) { e.printStackTrace(); } } }
主要就是实现了MessageListener的方法,并且这个类有MessageDriven的annotation,然后映射到SimpleQueue上。这样就能在这个jms消息队列有消息时,在onMessage方法中收到消息。
打包项目为一个ejb-jar,然后用glassfish发布。
运行之前的servlet,只要在浏览器地址栏里天上servlet对应的地址,我这里是http://localhost:8080/jmsServlet/Producer
glassfish的控制台就会输出servlet发送消息的println和mdb收到消息的println了
|
jms/SimpleQueue
|
|
jms/SimpleQueue
|