JMS简介

导读:
  1. JMS基本概念
  JMS(Java Message Service)是访问企业消息系统的标准API,它便于消息系
  统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发。
  
  
   2. JMS基本功能
  JMS是用于和面向消息的中间件相互通信的应用程序接口。它既支持点对点(point-to-point)的域,又支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。JMS还提供了另一种方式来对您的应用与旧的后台系统相集成。
   3. WebLogic JMS Server介绍
  WebLogic Server8.1符合JAVA规范,并通过Sun Microsystems J2EE 1.3认
  证.作为WebLogic的一部分,当然WebLogic JMS Server也完全遵从JMS规范,还支持集群,并可以应用于实际企业系统.下图是WebLogic JMS Server体系结构.图中可以看到WebLogic JMS Server主要组件有: WebLogic JMS servers(用于消息通信),Java客户端,JNDI(用于域名查找), 后备存储(用于持久消息存储,基于文件或者JDBC数据库).
  
  
   二. WebLogic JMS特性
  1. 消息通信模型
  JMS 支持两种消息通信模型:点到点(point-to-point)(PTP)模型和发布/订阅(Pub/Sub)模型。除了下列不同之外,这两种消息通信模型非常地相似:
  PTP 模型规定了一个消息只能有一个接收者;Pub/Sub 模型允许一个消息可以有多个接收者。
  2. 消息组成
  消息传递系统的中心就是消息。
  一条 Message 分为三个组成部分:
  头(header)是个标准字段集,客户机和供应商都用它来标识和路由消息。
  属性(property)支持把可选头字段添加到消息。如果您的应用程序需要不使用标准头字段对消息编目和分类,您就可以添加一个属性到消息以实现这个编目和分类。提供 set Property(...) 和 get Property(...) 方法以设置和获取各种 Java 类型的属性,包括 Object。JMS 定义了一个供应商选择提供的标准属性集。
  消息的主体(body)包含要发送给接收应用程序的内容。每个消息接口特定于它所支持的内容类型。
  JMS 为不同类型的内容提供了它们各自的消息类型,但是所有消息都派生自 Message 接口。
  StreamMessage:包含 Java 基本数值流,用标准流操作来顺序的填充和读取。
  MapMessage:包含一组名/值对;名称为 string 类型,而值为 Java 的基本类型。
  TextMessage:包含一个 String。
  ObjectMessage:包含一个 Serializable Java 对象;能使用 JDK 的集合类。
  BytesMessage:包含未解释字节流: 编码主体以匹配现存的消息格式。
  XMLMessage: 包含XML内容。扩展TextMessage,XMLMessage 类型的使用,使得消息过滤非常便利。
  3. 消息确认模式
  非事务性会话中,应用程序创建的会话有5 种确认模式,而在事务性会话中,确认模式被忽略。
  五种确认模式说明:
  AUTO_ACKNOWLEDGE:自动确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收。
  CLIENT_ACKNOWLEDGE:客户端确认模式。会话对象依赖于应用程序对被接收的消息调用一个acknowledge()方法。一旦这个方法被调用,会话会确认最后一次确认之后所有接收到的消息。这种模式允许应用程序以一个调用来接收,处理并确认一批消息。注意:在管理控制台中,如果连接工厂的Acknowledge Policy(确认方针)属性被设置为"Previous"(提前),但是你希望为一个给定的会话确认所有接收到的消息,那么就用最后一条消息来调用acknowledge()方法。
  DUPS_OK_ACKNOWLEDGE:允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。在需要考虑资源使用时,这种模式非常有效。注意:如果你的应用程序无法处理重复的消息的话,你应该避免使用这种模式。如果发送消息的初始化尝试失败,那么重复的消息可以被重新发送。
  NO_ACKNOWLEDGE:不确认模式。不确认收到的消息是需要的。消息发送给一个NO_ACKNOWLEDGE 会话后,它们会被WebLogic 服务器立即删除。在这种模式下,将无法重新获得已接收的消息,而且可能导致下面的结果:1. 消息可能丢失;和(或者)另一种情况:2. 如果发送消息的初始化尝试失败,会出现重复消息被发送的情况。
  MULTICAST_NO_ACKNOWLEDGE:IP组播下的不确认模式,同样无需确认。发送给一个MULTICAST_NO_ACKNOWLEDGE会话的消息, 会共享之前所述的NO_ACKNOWLEDGE 确认模式一样的特征。这种模式支持希望通过IP 组播方式进行消息通信的应用程序,而且无需依赖会话确认提供的服务质量。注意:如果你的应用程序无法处理消息的丢失或者重复,那么你应该避免使用这种模式。如果发送消息的初始化尝试失败的话,重复的消息可能会被再次发送。
  注:在上表的5 种确认模式中,AUTO_ACKNOWLEDGE ,DUPS_OK_ACKNOWLEDGE 和
  CLIENT_ACKNOWLEDGE 是JMS 规范定义的,NO_ACKNOWLEDGE 和MULTICAST_NO_ACKNOWLEDGE是WebLogic JMS 提供的。
   三. 配置JMS
  1. 创建连接工厂
  (1) 启动WebLogic Server8.1,登录控制台,选中JMS Connection Factories节点,点击右边的" Configure a new JMS Connection Factory...";
  
  
  (2) 填写连接工厂的名称SendJMSFactory和JNDI名称SendJMSFactory,点击"Create";
  
  
  (3) 勾上"myserver",将SendJMSFactory应用到myserver;
  
  
  2. 定义后备存储
  (1) 选中JMS Stores节点,点击右边的" Configure a new JMS Connection Factory...";
  
  
  (2) 填写文件后备存储的名称SendFileStore和目录Directionary E:/BEA/user_projects/domains/mydomain/sendfilestore,点击"Create".
  
  
  3. 创建JMS服务器
  (1) 选中JMS Servers节点,点击右边的" Configure a new JMSServer...";
  
  
  (2) 填写JMS服务器的名称SendJMSServer和Paging Store设为" SendFileStore",点击"Create";
  
  
  (3) Target选中"myserver",将SendJMSServer应用到myserver.
  
  
  4. 创建消息队列
  (1) 展开"SendJMSServer"节点,点击" Configure a new JMS Queue...";
  
  
  (2) 填写消息队列的名称SendJMSQueue和JNDI名称SendJMSQueue,点击"Create";
  
  
  四. JMS应用程序
  一个 JMS 应用程序由下列元素组成:
  JMS 客户机。 用 JMS API 发送和接收消息的 Java 程序。
  非 JMS(Non-JMS)客户机。 认识到这一点很重要 - 旧的程序经常成为整个 JMS 应用程序的一部分,而且它们的包含应该在设计时预先考虑。
  消息。 在 JMS 和非 JMS 客户机之间交换的消息的格式和内容是 JMS 应用程序设计所必须考虑的部分。
  JMS 供应商。供应商必须提供特定于其 MOM 产品的具体的实现。
  受管对象。 消息传递系统供应商的管理员创建了一个对象,它独立于供应商专有的技术。包括连接工厂ConnectionFactory和目的Destination。
  一种典型的 JMS 程序需要经过下列步骤才能开始消息产生和使用:
  通过 JNDI 查找 ConnectionFactory。
  通过 JNDI 查找一个或多个 Destination。
  用 ConnectionFactory 创建一个 Connection。
  用 Connection 创建一个或多个 Session。
  用 Session 和 Destination 创建所需的 MessageProducer 和 MessageConsumer。
  启动 Connection。
  下面利用上面配置的JMS资源演示点对点消息发送和接收的过程。
  五. 设计消息发送端
  1. 使用的JMS资源
  服务器URL: t3://localhost:80
  连接工厂: SendJMSFactory
  队列: SendJMSQueue
  2. 设计步骤
  初始化JNDI Tree
  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
  env.put(Context.PROVIDER_URL, PROVIDER_URL);
  return new InitialContext(env);
  lookup ConnectionFactory
  qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
  lookup Destination
  queue = (Queue) ctx.lookup(queueName);
  用 ConnectionFactory 创建Connection
  qcon = qconFactory.createQueueConnection();
  用 Connection 创建一个Session
  qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
  用 Session 和 Destination 创建MessageProducer
  qsender = qsession.createSender(queue);
  启动 Connection。
  qcon.start();
  发送消息
  msg = qsession.createTextMessage();
  msg.setText(message);
  qsender.send(msg);
  3. 源代码
  package jmssample;
  import java.util.Hashtable;
  import javax.jms.*;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  /** This example shows how to establish a connection
  * and send messages to the JMS queue. The classes in this
  * package operate on the same JMS queue. Run the classes together to
  * witness messages being sent and received, and to browse the queue
  * for messages. The class is used to send messages to the queue.
  *
  * @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
  */
  public class QueueSend
  {
  // Defines the JNDI context factory.
  public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
  // Defines the JNDI provider url.
  public final static String PROVIDER_URL=" t3://localhost:80";
  // Defines the JMS connection factory for the queue.
  public final static String JMS_FACTORY="SendJMSFactory";
  // Defines the queue.
  public final static String QUEUE="SendJMSQueue";
  private QueueConnectionFactory qconFactory;
  private QueueConnection qcon;
  private QueueSession qsession;
  private QueueSender qsender;
  private Queue queue;
  private TextMessage msg;
  /**
  * Creates all the necessary objects for sending
  * messages to a JMS queue.
  *
  * @param ctx JNDI initial context
  * @param queueName name of queue
  * @exception NamingException if operation cannot be performed
  * @exception JMSException if JMS fails to initialize due to internal error
  */
  public void init(Context ctx, String queueName)
  throws NamingException, JMSException
  {
  qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
  qcon = qconFactory.createQueueConnection();
  qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
  queue = (Queue) ctx.lookup(queueName);
  qsender = qsession.createSender(queue);
  msg = qsession.createTextMessage();
  qcon.start();
  }
  /**
  * Sends a message to a JMS queue.
  *
  * @param message message to be sent
  * @exception JMSException if JMS fails to send message due to internal error
  */
  public void send(String message) throws JMSException {
  msg.setText(message);
  qsender.send(msg);
  }
  /**
  * Closes JMS objects.
  * @exception JMSException if JMS fails to close objects due to internal error
  */
  public void close() throws JMSException {
  qsender.close();
  qsession.close();
  qcon.close();
  }
  /** main() method.
  *
  * @param args WebLogic Server URL
  * @exception Exception if operation fails
  */
  public static void main(String[] args) throws Exception {
  InitialContext ic = getInitialContext();
  QueueSend qs = new QueueSend();
  qs.init(ic, QUEUE);
  readAndSend(qs);
  qs.close();
  }
  private static void readAndSend(QueueSend qs)
  throws IOException, JMSException
  {
  BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
  String line=null;
  boolean quitNow = false;
  do {
  System.out.print("Enter message (/"quit/" to quit): ");
  line = msgStream.readLine();
  if (line != null &&line.trim().length() != 0) {
  qs.send(line);
  System.out.println("JMS Message Sent: "+line+"/n");
  quitNow = line.equalsIgnoreCase("quit");
  }
  } while (! quitNow);
  }
  private static InitialContext getInitialContext()
  throws NamingException
  {
  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
  env.put(Context.PROVIDER_URL, PROVIDER_URL);
  return new InitialContext(env);
  }
  }
  六. 设计消息接收端
  1. 使用的JMS资源
  服务器URL: t3://localhost:80
  连接工厂: SendJMSFactory
  队列: SendJMSQueue
  2. 设计步骤
  初始化JNDI Tree
  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
  env.put(Context.PROVIDER_URL, PROVIDER_URL);
  return new InitialContext(env);
  lookup ConnectionFactory
  qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
  lookup Destination
  queue = (Queue) ctx.lookup(queueName);
  用 ConnectionFactory 创建Connection
  qcon = qconFactory.createQueueConnection();
  用 Connection 创建一个Session
  qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
  用 Session 和 Destination 创建MessageConsumer
  qreceiver = qsession.createReceiver(queue);
  设置监听
  qreceiver.setMessageListener(this);
  启动 Connection
  qcon.start();
  3. 源代码
  package jmssample;
  import java.util.Hashtable;
  import javax.jms.*;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import java.util.Hashtable;
  import javax.jms.*;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  /**
  * This example shows how to establish a connection to
  * and receive messages from a JMS queue. The classes in this
  * package operate on the same JMS queue. Run the classes together to
  * witness messages being sent and received, and to browse the queue
  * for messages. This class is used to receive and remove messages
  * from the queue.
  *
  * @author Copyright (c) 1999-2003 by BEA Systems, Inc. All Rights Reserved.
  */
  public class QueueReceive implements MessageListener
  {
  // Defines the JNDI context factory.
  public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
  // Defines the JNDI provider url.
  public final static String PROVIDER_URL=" t3://localhost:80";
  // Defines the JMS connection factory for the queue.
  public final static String JMS_FACTORY="SendJMSFactory";
  // Defines the queue.
  public final static String QUEUE="SendJMSQueue";
  private QueueConnectionFactory qconFactory;
  private QueueConnection qcon;
  private QueueSession qsession;
  private QueueReceiver qreceiver;
  private Queue queue;
  private boolean quit = false;
  /**
  * Message listener interface.
  * @param msg message
  */
  public void onMessage(Message msg)
  {
  try {
  String msgText;
  if (msg instanceof TextMessage) {
  msgText = ((TextMessage)msg).getText();
  } else {
  msgText = msg.toString();
  }
  System.out.println("Message Received: "+ msgText );
  if (msgText.equalsIgnoreCase("quit")) {
  synchronized(this) {
  quit = true;
  this.notifyAll(); // Notify main thread to quit
  }
  }
  } catch (JMSException jmse) {
  jmse.printStackTrace();
  }
  }
  /**
  * Creates all the necessary objects for receiving
  * messages from a JMS queue.
  *
  * @param ctx JNDI initial context
  * @param queueName name of queue
  * @exception NamingException if operation cannot be performed
  * @exception JMSException if JMS fails to initialize due to internal error
  */
  public void init(Context ctx, String queueName)
  throws NamingException, JMSException
  {
  qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
  qcon = qconFactory.createQueueConnection();
  qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
  queue = (Queue) ctx.lookup(queueName);
  qreceiver = qsession.createReceiver(queue);
  qreceiver.setMessageListener(this);
  qcon.start();
  }
  /**
  * Closes JMS objects.
  * @exception JMSException if JMS fails to close objects due to internal error
  */
  public void close()throws JMSException
  {
  qreceiver.close();
  qsession.close();
  qcon.close();
  }
  /**
  * main() method.
  *
  * @param args WebLogic Server URL
  * @exception Exception if execution fails
  */
  public static void main(String[] args) throws Exception {
  InitialContext ic = getInitialContext();
  QueueReceive qr = new QueueReceive();
  qr.init(ic, QUEUE);
  System.out.println("JMS Ready To Receive Messages (To quit, send a /"quit/" message).");
  // Wait until a "quit" message has been received.
  synchronized(qr) {
  while (! qr.quit) {
  try {
  qr.wait();
  } catch (InterruptedException ie) {}
  }
  }
  qr.close();
  }
  private static InitialContext getInitialContext()
  throws NamingException
  {
  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
  env.put(Context.PROVIDER_URL, PROVIDER_URL);
  return new InitialContext(env);
  }
  }
  七. 测试消息发送和接收
  1. 设置WebLogic Classpath;
  
  
  2. 转到发送接收程序目录编译文件;
  
  
  3. 执行接受程序;
  4. 打开另一窗口,执行发送程序;
  
  
  5. 输入发送消息"quit",接收程序结束.
  
  
   总结
  本文先简要介绍了JMS的一些基本概念,继而引入了WebLogic JMS Server的体系结构和相关特性。在此基础之上,图文并茂地讲述了JMS在WebLogic Server 8.1上的配置。最后在解剖JMS应用程序框架的同时,以点对点为例演示了JMS的发送接收消息流程。

本文转自
http://www.blogjava.net/tbest/articles/174378.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值