**先来写个小demo,看看它究竟实现怎样的效果:
拟定简单的场景:消息推送端发送公司dto信息,消息接收端解析回dto进行业务处理。**
step1 : 在pom中定义好依赖类库。
<!-- mq发收消息 -->
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
step2: 定义业务dto。
package com.ebdt.demo.activemq;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.msyd.contract.ContractException;
public class CompanySignDto {
private String cpmpanyName;
private String code;
private String sealCode;
private String sealPassword;
private String operatorCode;
private String reason;
/**
* 将dto转换成json数据
* @param protocol
* @return
*/
public static String toJson(CompanySignDto dto) {
return JSON.toJSONString(dto);
}
/**
* 将json数据转换成bean
* @param json
* @return
*/
public static CompanySignDto toBean(String json) {
try {
if (json == null) {
throw new ContractException("参数为空");
}
CompanySignDto dto = JSONObject.parseObject(json, CompanySignDto.class);
return dto;
} catch (Exception e) {
throw new ContractException("获取数据出现异常:" + e.getMessage() + ";" + json);
}
}
public String getCpmpanyName() {
return cpmpanyName;
}
public void setCpmpanyName(String cpmpanyName) {
this.cpmpanyName = cpmpanyName;
}
public String getCode() {
return code;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public void setCode(String code) {
this.code = code;
}
public String getSealCode() {
return sealCode;
}
public void setSealCode(String sealCode) {
this.sealCode = sealCode;
}
public String getSealPassword() {
return sealPassword;
}
public void setSealPassword(String sealPassword) {
this.sealPassword = sealPassword;
}
public String getOperatorCode() {
return operatorCode;
}
public void setOperatorCode(String operatorCode) {
this.operatorCode = operatorCode;
}
@Override
public String toString() {
return "CompanySignDto [cpmpanyName=" + cpmpanyName + ", code=" + code + ", sealCode=" + sealCode
+ ", sealPassword=" + sealPassword + ", operatorCode=" + operatorCode + "]";
}
}
step3: 定义消费者,这个消费者启动,等消息推送,消费者就会接收到。
package com.ebdt.demo.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
/**使用jms-1.1.jar包 */
public class Consumer {
public static void main(String[] args) {
// JMS 客户端到JMS Provider 的连接
Connection connection = null;
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
connection = connectionFactory.createConnection();//构造从工厂得到连接对象
connection.start(); //启动
//获取操作连接
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
//获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
Destination destination = session.createQueue("FirstQueue");//指定要获取消息的队列
MessageConsumer consumer = session.createConsumer(destination); // 消费者 获取队列中的消息
while (true) {
//设置接收者接收消息的时间,便于测试,这里先定为100s
TextMessage message = (TextMessage) consumer.receive(100000);
if (null != message) {
CompanySignDto dto = CompanySignDto.toBean(message.getText());
System.out.println("收到消息" + dto.toString());
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
step4: 定义生产者,本例生产者的消息只推送一次,如果消费者正在启动,则mq监听到后会直接收到消息,如果生产者推送消息后,消费者服务没启动,那么消费者后期启动后会接收到这个消息。
package com.ebdt.demo.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ms.ebdt.json.util.PrincipalScale;
/**jms-1.1.jar包运用*/
public class Producer {
public static Log logger = LogFactory.getLog(PrincipalScale.class);
private static final int SEND_NUMBER = 5;
public static void main(String[] args) {
Connection connection = null;
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://10.1.64.120:61616");//jms创建连接的工厂, 构造ConnectionFactory实例化对象,采用ActiveMq实现jar(activemq-core.jar)
try {
connection = connectionFactory.createConnection();// 从工厂获取连接资源
connection.start(); // 启动JMS客户端 到 JMS生产值 的连接
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);// 从连接中获取 一个发送或接收消息的Session
// Destination :消息发送给哪个队列.获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
Destination destination = session.createQueue("FirstQueue");
MessageProducer producer = session.createProducer(destination);// 得到生产者
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);// 设置不持久化,作为练习,实际根据项目决定
sendMessage(session, producer);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
public static void sendMessage(Session session, MessageProducer producer) throws Exception {
CompanySignDto dto = new CompanySignDto();
dto.setCode("code");
dto.setCpmpanyName("cpmpanyName");
dto.setSealCode("sealCode");
dto.setSealPassword("sealPassword");
dto.setOperatorCode("operatorCode");
dto.setReason("要把我发出去呀,这是第" + 1 + "次");
String msg = dto.toJson(dto);
logger.info(msg);
TextMessage message = session.createTextMessage(msg);
// 发送消息
producer.send(message);
}
}
step5:生产者和消费者没有特定的启动顺序, 运行生产者,把推送消息打印在控制台:
INFO 07-25 09:44:10(Producer.java:66): {"code":"code","cpmpanyName":"cpmpanyName","operatorCode":"operatorCode","reason":"要把我发出去呀,这是第1次","sealCode":"sealCode","sealPassword":"sealPassword"}
运行消费者,接收到消息为:
收到消息CompanySignDto [cpmpanyName=cpmpanyName, code=code, sealCode=sealCode, sealPassword=sealPassword, operatorCode=operatorCode]
以上是完全通过代码来实现发送接收消息的,它的运作过程一目了然,方便按照以上步骤解读源码。下篇文章的消息推送和消费 会更接近实际运用场景。方式:xml+pojo 。
附:如果在启动生产者/消费者的时候,出现如下错误:
javax.jms.JMSException: Could not connect to broker URL: tcp://10.1.64.120:61616. Reason: java.net.ConnectException: Connection refused: connect
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:35)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:293)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:238)
at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:184)
at com.ebdt.demo.activemq.Producer.main(Producer.java:30)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.activemq.transport.tcp.TcpTransport.connect(TcpTransport.java:504)
at org.apache.activemq.transport.tcp.TcpTransport.doStart(TcpTransport.java:467)
at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55)
at org.apache.activemq.transport.AbstractInactivityMonitor.start(AbstractInactivityMonitor.java:132)
at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58)
at org.apache.activemq.transport.WireFormatNegotiator.start(WireFormatNegotiator.java:72)
at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58)
at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:273)
... 3 more
基本是两个原因,1 没有安装mq 2 没有启动mq
启动就不谈了,说下windows安装部署mq:请参看:windows7 安装部署activemq以及启动.