`

JMS:Java消息服务(Java Message Service)初学笔记

    博客分类:
  • JMS
jms 
阅读更多
JMS:Java消息服务(Java Message Service)
初学JMS,记录下心得
一什么是JMS,什么是activeMq?
1JMS是一种有关面向消息中间件的技术规范,读了李刚的经典java EE企业应用实战之后。我觉得可以理解为,为了解决RMI,CORBA,WebService等技术的同步通信,客户端和服务器端生命周期耦合等缺点的一种技术。它实现了完全解耦,它能让消息生产者和消息消费者之间的完全隔离。而这种隔离就需要面向消息服务器的支持,这个消息服务器就是activeMq和类似其他的服务器。此外,我们也可以理解JMS类似JDBC,他屏蔽了不同厂家的消息服务器。不管底层采用何种消息服务器。应用程序只要使用JMS提供的API即可,不需要了解底层的各个服务器的细节内容。
2.activeMq,引用百度百科的说法,要使用Java消息服务,你必须要有一个JMS提供者,管理会话和队列。这里我们理解为它就是JMS服务的提供者。JMS消息生产者和消费者都需要连接到这个JMS服务提供者。
3.注意JMS中的消息生产者,消费者和消息目的,我们可以把它看做是使用JMS服务提供者所提供的服务的客户端。所以就有了connection.setClientID("MyClient");当然从这句话的实际用途来看,他是为了完成可靠地消息传输的。消息目的,我们理解为消息生产者发送消息的目的地,也是消息消费者获取消息的消息源。我理解其就存在消息提供者

二 Java消息服务支持两种消息模型:Point-to-Point消息(P2P;即:点对点)和发布订阅消息(Publish Subscribe messaging,简称Pub/Sub;即:广播式)
1什么是P2P?引用百度百科的说法,P2P是英文Peer-to-Peer(对等)的简称,又被称为“点对点”。“对等”技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都聚集在较

少的几台服务器上。我的理解就是一台计算机并不是通过服务器来和其他计算机连接,而是直接和其他计算机连接。
2什么是Pub/Sub?在这种模型中,信息消费者和生产者参与消息的传输。生产者“发布”事件,而消费者“订阅”感兴趣的事件并消费事件。生产者把消息把与特定主题关联起来,然后消息传递系统根

据消费者所注册的感兴趣主题,把消息路由给消费者。也就是说这种就是广播式的模式。

或者我们也可以理解为,PTP是类似邮件系统,而Pub/Sub类似BBS,邮件系统不管消息消费者是否在线,只要消息还处于有效期内,该消息消费者总可以从消息队列中提取该消息,而Pub/Sub,如果消息消费者处于离线状态,就会错过消息,正像如果我们一段时间不登陆BBS,再登陆的话,之前的信息就不知道
三JMS它是使用JNDI的相应方法来实现其操作的。
1JNDI,一组在java应用中访问命名和目录服务的API,什么是目录服务,我的理解是它提供了一个服务名字和服务的具体网络物力地址的映射,有了这个映射,我们只需要通过名字就可以访问到具体的

服务。

四一个典型的JMS程序要经过以下步骤才能开始创建和使用消息
1、通过JNDI查询ConnectionFactory
2、用ConnectionFactory创建一个Connection
3、用Connection创建一个或多个Session
4、通过JNDI查询一个或多个Destination
5、用Session和Destination创建对应的MessageProducer和MessageConsumer
6、启动Connection

消息选择是一种选择机制,类似于SQL的查询条件。

五实例

1.当然我们必须先启动activeMq服务器,提供JMS服务。

2.发送消息例子:
package com.flvcd.servlet;
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.jms.Connection; 
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode; 
import javax.jms.Destination; 
import javax.jms.JMSException;
import javax.jms.Message; 
import javax.jms.MessageListener; 
import javax.jms.MessageProducer;
import javax.jms.Session; 
import javax.naming.Context; 
import javax.naming.InitialContext; 
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse;
public class MyPublish extends HttpServlet implements MessageListener {
	private InitialContext initCtx; 
	private Context envContext; 
	private ConnectionFactory connectionFactory;  
	private Connection connection;  
	private Session jmsSession; 
	private MessageProducer producer;
	public void onMessage(Message message) {
		
	}
	public MyPublish(){
		super();
	}
	public void destroy(){
		super.destroy();
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {
		doPost(request, response);  
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
		String content=request.getParameter("content");   //设置持久方式   
		try {    
			producer.setDeliveryMode(DeliveryMode.PERSISTENT);   
			Message testMessage = jmsSession.createMessage();    // 发布刷新文章消息 
			testMessage.setStringProperty("RefreshArticleId", content);    
			producer.send(testMessage);    // 发布刷新帖子消息    
			testMessage.clearProperties();   
			testMessage.setStringProperty("RefreshThreadId", content);   
			producer.send(testMessage);   
			} catch (Exception e) {  
				e.printStackTrace();   
			}
		}
	public void init() throws ServletException {   // Put your code here  
		try {    
			initCtx = new InitialContext();  
			envContext = (Context) initCtx.lookup("java:comp/env");    
			connectionFactory = (ConnectionFactory) envContext.lookup("jms/NormalConnectionFactory");  
			connection = connectionFactory.createConnection();   
			jmsSession = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);    
			producer = jmsSession.createProducer((Destination) envContext.lookup("jms/topic/MyTopic"));    
			} catch (NamingException e) {  
				e.printStackTrace();  
				} catch (JMSException e) { 
					e.printStackTrace();
				}
	}
		
	
}



 

3.接收消息例子:

package com.flvcd.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;
import javax.jms.*;
import org.apache.activemq.ActiveMQConnectionFactory;
public class JMSListener extends HttpServlet implements MessageListener{
    /** 初始化jms连接,创建topic监听器 */
    public void init(ServletConfig config) throws ServletException{        
        try {
            InitialContext initCtx = new InitialContext();
            Context envContext = (Context) initCtx.lookup("java:comp/env");
            ConnectionFactory connectionFactory = (ConnectionFactory) envContext.lookup("jms/FailoverConnectionFactory");
            Connection connection = connectionFactory.createConnection();
            connection.setClientID("MyClient");
            Session jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
            //普通消息订阅者,无法接收持久消息
            //MessageConsumer consumer = jmsSession.createConsumer((Destination) envContext.lookup("jms/topic/MyTopic"));
            //基于Topic创建持久的消息订阅者,前提:Connection必须指定一个唯一的clientId,当前为MyClient
            TopicSubscriber consumer = jmsSession.createDurableSubscriber((Topic) envContext.lookup("jms/topic/MyTopic"), "MyClient");
            consumer.setMessageListener(this);
            connection.start();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    /** 接收消息,做对应处理 */
    public void onMessage(Message message) {
        if (checkText(message, "RefreshArticleId") != null) {
            String articleId = checkText(message, "RefreshArticleId");
            System.out.println("接收刷新文章消息,开始刷新文章ID=" + articleId);
        } 
        else if (checkText(message, "RefreshThreadId") != null) {
            String threadId = checkText(message, "RefreshThreadId");
            System.out.println("接收刷新论坛帖子消息,开始刷新帖子ID=" + threadId);
        } else {
            System.out.println("接收普通消息,不做任何处理!");
        }
    }
    private static String checkText(Message m, String s) {
        try {
            return m.getStringProperty(s);
        } catch (JMSException e) {
            e.printStackTrace(System.out);
            return null;
        }
    }
}


注意这里是使用MessageListener,也就是使用异步接受的方式,接收程序在没有收到消息之前不会被阻塞。如果有JMS消息到达时,JMS消息监听器的监听方法onMessage()方法会被触发。同时,我们必须为消息消费者绑定消息监听器,这就引出了可靠地JMS订阅者。
consumer.setMessageListener(this);

4.配置web.xml
<servlet>  
 	 <servlet-name>jms-listener</servlet-name>  
  	<servlet-class>  com.flvcd.servlet.JMSListener</servlet-class>  
  	<load-on-startup>1</load-on-startup>  
  </servlet>


5.此外还有修改context.xml以JNDI的方式定义了ActiveMQ的broker连接url、Topic和Queue。和修改activemq.xml等内容
详见http://wenku.baidu.com/view/1cab03d380eb6294dd886cbc.html
六编程时报的错误处理
关于jndi报的一些错误
错误一:
引用
Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
解决方法:配置properties
  Properties properties = new Properties(); 
            properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory"); 
            properties.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); 
            properties.setProperty(Context.PROVIDER_URL, "localhost:1099");  
关于jndi的写法wangh8080.blog.163.com/blog/static/197848297201241644436227/
错误二:
引用
cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]
 
解决方法:引入jbossall-client.jar包
错误三:
引用
Could not obtain connection to any of these urls: localhost:1099
解决方法:eclipse集成jboss,
什么是JBoss?它是一个基于J2EE的开放源代码的应用服务器。
详情参见http://www.cnblogs.com/FIX-GPS/archive/2012/06/27/2566370.html
当然也可以使用http://wenku.baidu.com/view/1cab03d380eb6294dd886cbc.html来编写自己的JMS实例
分享到:
评论

相关推荐

    java学习笔记

    这本书涉及了消息服务(Message-oriented middleware,MOM)和Java消息服务(Java Message Service,JMS),并专注于Apache ActiveMQ消息代理。 基于此,我们将从描述中提取Java学习经验,并结合Apache ActiveMQ的...

    任小龙java全部笔记

    12. **Java SE与Java EE的区别**:Java SE(标准版)是基础,而Java EE(企业版)则包含了更多的企业级功能,如Web服务、EJB(Enterprise JavaBeans)、JMS(Java Message Service)等。 这些笔记不仅包含理论知识...

    达内java笔记,精挑细选(达内助教整理)

    它包括了一系列的Java API和服务,如Servlet、JSP、EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JTA(Java Transaction API)等,旨在简化开发、部署和管理企业级应用的过程。 1. **Servlet**:...

    达内java笔记,精挑细选(达内助教整理)0积分

    J2EE平台由多个组件构成,如Servlet、JSP(JavaServer Pages)、EJB(Enterprise JavaBeans)、JMS(Java Message Service)等。Servlet是处理HTTP请求的主要工具,JSP用于生成动态网页内容,而EJB则提供了服务器端...

    Java JDK 6学习笔记——ppt

    13. **Java EE(Enterprise Edition)**:Java平台的企业版,包括EJB(Enterprise JavaBeans)、JMS(Java Message Service)等,用于构建分布式企业应用。 通过这份PPT学习笔记,你可以系统地学习和掌握Java JDK 6...

    Java JDK 6学习笔记——ppt简体版

    10. **JNDI与JMS**:Java Naming and Directory Interface(JNDI)用于查找和绑定分布式系统中的资源,Java Message Service(JMS)则是Java消息传递的标准。这两个技术在企业级应用中广泛使用。 通过这份Java JDK ...

    j2ee.rar_java 学习笔记

    JMS(Java Message Service)** JMS允许Java应用程序创建、发送、接收和读取消息。消息驱动bean是JMS在Java EE中的应用,常用于解耦系统组件。 **8. 配置与部署** Java EE应用通常包含多个组件,部署时需要使用...

    北京圣思园java课堂笔记 (javaSE和javaee)

    JavaEE的核心组件包括Servlet、JSP、EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JPA(Java Persistence API)等。学习JavaEE需要理解这些组件的作用及其在企业级应用开发中的应用。 3. **笔记的...

    java ,bootstrap,servlet,javaWep基本笔记.zip

    它包括了多种技术和规范,如Servlet、JavaServer Pages (JSP)、JavaServer Faces (JSF)、Java Persistence API (JPA) 和Java Message Service (JMS) 等。Java Web应用通常运行在Java EE服务器上,提供动态内容生成、...

    软件工程师学习笔记J2EE

    4. **JMS**:Java消息服务允许应用程序之间异步通信。笔记可能包含了消息队列的概念、消息模型以及如何使用JMS API创建和消费消息。 5. **JTA**:Java事务API提供了处理分布式事务的能力。笔记可能会涵盖事务的ACID...

    J2EE学习笔记(J2ee初学者必备手册)

    3. **消息驱动bean(Message-Driven Beans)**:处理JMS(Java Message Service)消息,常用于异步通信。 **Web服务** J2EE支持创建和消费Web服务,通过SOAP(Simple Object Access Protocol)和WSDL(Web ...

    2010年J2EE学习笔记

    6. **JMS**和**JCA**:Java消息服务和Java连接器体系结构,是J2EE中用于异步通信和整合不同系统的重要工具。 7. **XML和SOAP**:XML用于数据交换,而SOAP是基于XML的Web服务协议,两者结合实现了不同系统间的远程...

    J2EE学习笔记(J2ee初学者必备手册)

    6. **Java Message Service (JMS)**:JMS允许应用之间通过消息传递进行异步通信,是分布式系统中重要的通信机制。 7. **Java API for Web Services (JAX-WS)** 和 **Java API for RESTful Web Services (JAX-RS)**...

    Java-J2EE全部学习笔记 培训结构的学习资料

    8. **EJB与JMS**:EJB(Enterprise JavaBeans)提供了一种在服务器端创建可复用组件的方式,而JMS(Java Message Service)则用于异步消息传递。学习笔记可能讲解这两者在企业级应用中的应用。 9. **Web容器与应用...

    java后端学习笔记

    本篇文章将深入探讨“java后端学习笔记”中的关键知识点,包括消息队列(Message Queuing)服务如ActiveMQ和RabbitMQ、工作流引擎Activity、容器化技术Docker、分布式服务框架Dubbo、网络库Netty、RPC(Remote ...

    Java学习笔记.zip

    JavaEE是Java在企业级应用开发中的扩展,它增加了如Servlet、JSP、JavaServer Faces (JSF)、Java Persistence API (JPA)、Java Message Service (JMS)等技术,用于构建分布式、数据库驱动的应用。在"电子书"中,可能...

    java2

    4. **JMS**:Java Message Service提供了异步通信的机制,使得应用程序可以通过消息传递进行解耦,提高系统的可伸缩性和可靠性。 5. **JPA**:Java Persistence API是Java的标准ORM(对象关系映射)规范,允许...

    Java帮助文档大全

    5. **Java Message Service (JMS)**:支持消息传递,常用于分布式系统中的异步通信。 6. **Java Transaction API (JTA)** 和 **Java Transaction Service (JTS)**:处理分布式事务管理。 Java帮助文档大全中可能...

    CXF webservice初学笔记

    9. `geronimo-jms_1.1_spec-1.1.1.jar`:Geronimo对Java Message Service (JMS) 1.1规范的实现,用于异步消息传递,是企业级应用中常见的一种通信方式。 通过学习CXF Webservice,开发者将能够理解如何定义服务接口...

    JAVAWEB开发实战经典(课堂笔记)

    5. **Java EE相关技术**:包括JNDI(Java Naming and Directory Interface)、JTA(Java Transaction API)和JMS(Java Message Service)等,这些在企业级Java应用中广泛使用,笔记可能涉及这些技术的基本概念和...

Global site tag (gtag.js) - Google Analytics