`

准备开始学JMS(转)

    博客分类:
  • ejb
阅读更多
最近几天项目刚上线,这几天估计不会有太多的事情。我也想学点东西,刚好利用这个时间学习一下JMS,现在就从基础开始学习JMS,以下为网上资料转载:
一. 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<Type>Property(...) 和 get<Type>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消息模型 JMS学习.doc

    - **异步处理**:JMS允许应用程序发送消息后继续执行其他任务,而接收方可以在准备好处理消息时才接收,提高了系统的响应速度和效率。 - **解耦**:通过消息传递,生产者和消费者无需直接相互了解,降低了系统间的...

    jms.rar_jar j_java jms_jms_jms jar_jms.j

    描述中的"java消息系统 JMS 学习代码 例子 jar"表明这个压缩包是为了学习JMS而准备的,里面包含了示例代码,便于开发者理解和实践JMS的工作原理。`jar`文件通常用于打包和分发Java类库,这里可能是为了方便导入和...

    jms英文书小合集

    例如,通过消息队列,一个组件可以无阻塞地处理大量请求,而其他组件则在准备好处理这些请求时再从中取出消息。 7. **实际案例与最佳实践**: 书籍可能还会涵盖如何在实际项目中应用JMS,提供各种使用场景和最佳实践...

    jms整合spring工程

    本项目"jms整合spring工程"是一个已经准备就绪的Java工程,它展示了如何在Spring框架中集成JMS,以便利用消息队列进行通信。主要依赖的是Apache ActiveMQ,这是一款流行的开源JMS提供者,能够实现高效、可靠的实时...

    JAVA企业级API-JMS

    此代码段展示了如何初始化JMS的相关组件,例如`QueueConnection`、`QueueConnectionFactory`等,并为发送消息做准备。需要注意的是,实际的发送逻辑以及其他必要的异常处理部分并未完全展示出来,开发者需要根据实际...

    java实现的基于jms协议的消息队列中间件,源码!

    2. **消息消费者**:消费者从队列中取出并处理消息,它们可以在准备好处理消息时才进行消费,实现解耦。 3. **消息队列**:作为存储和转发的媒介,消息队列保证了消息的顺序,并在必要时进行消息的持久化,以防系统...

    SonicMQ中jms小程序

    通过异步处理,生产者可以发送消息后立即继续执行其他任务,而消费者可以在准备好时才处理消息,提高了系统的响应速度和并发能力。 4. **编程接口**:使用JMS API,开发者可以创建Producer来发送消息,创建Consumer...

    使用JMS和ESB构建强大而可靠的SOA

    在第二部分,我们将探讨一个具体的ESB场景,学习如何创建服务消费者和服务提供者,并准备它们之间的交互。而在第三部分,我们将通过实例演示如何在WebSphere ESB中构建中介,这个中介负责处理服务间的通信,包括可能...

    ActiveMq-JMS好用实例详解

    ### ActiveMQ-JMS好用实例详解 #### 一、ActiveMQ简介及特点 **ActiveMQ** 是一个非常流行的开源消息中间件,它基于 **Java消息服务(JMS)** 规范,能够提供高度可靠的消息传递机制。ActiveMQ 以其丰富的功能集、...

    学习文档希望能够帮助到大家

    J2EE是一个用于构建分布式、多层企业级应用的平台,其核心特性包括Servlet、JSP(JavaServer Pages)、EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JTA(Java Transaction API)等。这些技术是...

    新手学习Java路线图

    - 学习如何准备Java相关职位的面试。 - 掌握面试中常见的问题及其解答技巧。 3. **就业指导** - 掌握求职过程中的注意事项。 - 学习简历制作和面试技巧。 通过以上详细的讲解,相信你已经对Java学习路线有了...

    Java学习路线图,专为新手定制的Java学习计划建议.pdf

    对于新手来说,建议按部就班地从J2SE开始,逐步深入到J2EE,同时结合实际项目进行练习,以便更好地掌握这些知识,并为将来的就业做好准备。在学习过程中,选择合适的视频教程,如孙鑫和张孝祥的课程,可以帮助理解并...

    Qpid学习文档

    - **Store-and-forward**:消息被存储直到接收者准备好接收,支持异步消息交换。 2. **中间件的需求**: - **大量数据交换**:在企业级应用中,需要处理海量数据,保证消息的可靠性至关重要。 - **灵活性**:...

    java学习路线图 java学习路线图

    - **JMS、JMX、JTA**:掌握Java消息服务、管理扩展和事务管理。 - **SOA和WebService**:理解面向服务架构和服务间的通信。 - **工作流和JBPM**:了解流程管理和工作流引擎。 - **搜索引擎与Lucene**:学习如何...

    新手如何学习java(java学习建议路线图).doc

    最后,通过实践项目来巩固所学知识,提高解决问题的能力,为找工作做好准备。 总之,学习Java是一个逐步深入的过程,需要耐心和毅力。从基础开始,逐渐接触更复杂的概念和技术,不断练习和实践,才能成为一名熟练的...

    Java学习路线图,专为新手定制的Java学习计划建议[借鉴].pdf

    首先,初学者需要从J2SE(Java 2 Platform Standard Edition)开始,这是Java的基础,主要包括面向对象的概念、Java基本语法、桌面图形界面应用程序的开发以及常用API的使用。对于Java基础,学习者应深入理解面向...

Global site tag (gtag.js) - Google Analytics