Spring Cloud -- 使用activemq完成注册发送邮件

1.启动activemq服务端,并查看服务是否启动:

在这里插入图片描述
在这里插入图片描述

2.引入activemq依赖,配置消息生产者activemq信息:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-broker</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.jms</groupId>
            <artifactId>javax.jms-api</artifactId>
        </dependency>
# 消息生产者配置信息
spring: 
	activemq:
	    broker-url: tcp://localhost:61616
	    user: admin
	    password: admin
	    in-memory: true
	    pool:
	      enabled: false

## 队列名称(查看activemq时队列名称会是这个),供生产者读取
messages:
  queue: mail_queue

3.建立注册邮件消息生产者

在这里插入图片描述

package com.id0304.mq.producer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.jms.Destination;
import java.util.HashMap;
import java.util.Map;

//往消息服务推送邮件信息,消息队列生产者
@Service("registerMailboxProducer")
public class RegisterMailboxProducer {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    public void send(Destination destination, String json){
        jmsMessagingTemplate.convertAndSend(destination,json);
    }
}

4.调用生产者创建队列:

package com.id0304.manage.impl;

import com.alibaba.fastjson.JSONObject;
import com.id0304.constants.DBTableName;
import com.id0304.constants.MQInterfaceType;
import com.id0304.dao.UserDao;
import com.id0304.entity.UserEntity;
import com.id0304.manage.UserServiceManage;
import com.id0304.mq.producer.RegisterMailboxProducer;
import com.id0304.utils.DateUtils;
import com.id0304.utils.Md5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.jms.Destination;


@Service
@Slf4j
public class UserServiceManageImpl implements UserServiceManage {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RegisterMailboxProducer registerMailboxProducer;

	//读取配置文件的队列名
    @Value("${messages.queue}")
    private String MESSAGES_QUEUE;

    //注册服务
    @Override
    public void regist(UserEntity userEntity) {
        userEntity.setCreated(DateUtils.getTimestamp());
        userEntity.setUpdated(DateUtils.getTimestamp());
        String password = userEntity.getPassword();
        String phone = userEntity.getPhone();
        userEntity.setPassword(MD5PasswordSalt(phone,password));
        userDao.save(userEntity, DBTableName.TABLE_MB_USER);
        
        //创建名为MESSAGES_QUEUE属性值的队列
        Destination destination = new ActiveMQQueue(MESSAGES_QUEUE);
        //组装报文格式得到一个json字符串,自定义报文方法mailMessage在下面
        String mailMessage = mailMessage(userEntity.getEmail(),userEntity.getUsername());
        //输出日志
        log.info("###regist() 注册发送邮件报文mailMessage:{}",mailMessage);
        //向ActiveMQ推送消息(指明消息目的名称和消息内容)
        registerMailboxProducer.send(destination,mailMessage);
    }

    //组装自定义报文,根据实际情况自定义
    /**
     * 这里注意,我们是将一个json字符串存进了队列里作为自定义的消息队列报文,格式如下:
     * "root" : {
     *              "header" : {
     * 					//接口类型也是自定义的,这里定义了一个发送邮件的接口类型sms_mail,供消费者识别:
     *                  "interfaceType" : "sms_mail"
     *              },
     *              "content" : {
     *                  //消息体内容,即要传什么数据到队列里,这里传了email地址和用户名
     *                  email : "",
     *                  username : ""
     *              }
     *          }
     * @param email
     * @param username
     * @return
     */
    @Override
    public String mailMessage(String email,String username){
        JSONObject root = new JSONObject();
        JSONObject header = new JSONObject();
        header.put("interfaceType",MQInterfaceType.SMS_MAIL);
        JSONObject content = new JSONObject();
        content.put("mail",email);
        content.put("username",username);
        root.put("header",header);
        root.put("content",content);
        return root.toString();
    }
}

5.调用这个接口,消息就会被推送到ActiveMQ:

这里队列有1个消息,消费者数为0,入队的有1个,出队数目为0:
在这里插入图片描述

6.接下来,我们来创建一个消费者来对这个消息进行消费:

由于消息服务也是一个较大的服务,所以单独提取出来作为一个工程,建立消息服务:
在这里插入图片描述

1) 配置消费者,注册该服务进eureka,集成邮件发送:

server:
  port: 8763
  context-path: /message

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: message

  activemq:
    broker-url: tcp://localhost:61616
    user: admin
    password: admin
    in-memory: true
    pool:
      enabled: false

  mail:
      username: xxxx@qq.com
      password: xxxx
      host: smtp.qq.com
      # qq邮箱要求ssl安全连接,这里需要开启ssl
      properties:
        mail.smtp.ssl.enable=true

2) 首先建立消费者适配器接口MessageAdapter,提高扩展性:

package com.id0304.adapter;

import com.alibaba.fastjson.JSONObject;

//所有消息都会交给他进行转发
//此后若要增加不同类型的消费者(短信,公众号推送等),可以进行拓展
public interface MessageAdapter {
    //接受消息
    public void distribute(JSONObject jsonObject);
}

3) 建立消费者服务SMSMailboxService继承MessageAdapter接口:

关于邮箱发送任务,详见我的另一篇博客:https://mp.csdn.net/mdeditor/90322248#

package com.id0304.service;

import com.alibaba.fastjson.JSONObject;
import com.id0304.adapter.MessageAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class SMSMailboxService implements MessageAdapter {
	//集成发送邮件
    @Autowired
    private JavaMailSender mailSender;  //自动注入bean

	//这里需要传入一个消息体(包含mail和username)json对象content,完成邮箱发送服务,真正发送邮件的服务
    @Override
    public void distribute(JSONObject jsonObject) {
        String username = jsonObject.getString("username");	//获取用户名
        String mail = jsonObject.getString("mail");	//获取邮箱
        log.info("###消费者收到消息...mail:{}",mail,username);	//日志
        //发送邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("xxxx@qq.com");
        message.setTo(mail);
        message.setSubject("欢迎!!");
        message.setText("欢迎注册!使用邮件任务...");
        log.info("###发送短信邮箱:{}",mail);
        mailSender.send(message);
    }
}

4) 接下来创建接受并消费服务的方法ConsumerDistribute:

package com.id0304.mq.distribute;

import com.alibaba.fastjson.JSONObject;
import com.id0304.adapter.MessageAdapter;
import com.id0304.constants.MQInterfaceType;
import com.id0304.service.SMSMailboxService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

//消费消息mq 从队列获取最新消息
@Slf4j
@Component
public class ConsumerDistribute {

    @Autowired
    private SMSMailboxService smsMailboxService;

	//监听消息队列,这里注意队列名要对上,方法参数是刚刚我们存进去的json字符串
    @JmsListener(destination = "mail_queue")
    public void distribute(String json){
        log.info("###消息服务###收到消息,消息内容json:{}",json);
        if(StringUtils.isEmpty(json)){	//判空
            return;
        }
        //将json字符串转化为json对象
        JSONObject jsonObject = new JSONObject().parseObject(json);
        //获取json对象里的头信息(我们自定义的json报文格式)
        JSONObject header = jsonObject.getJSONObject("header");
        //获取json对象的接口信息
        String interfaceType = header.getString("interfaceType");
        //创建适配器,以下会根据消息类型判断使用哪个实现类,会实现实现该接口的distribute方法
        MessageAdapter messageAdapter = null;
        //判断接口类型(这里只写了一个邮箱,公众号推送等可以自行补充)
        switch (interfaceType){
            //根据消息类型是SMS_MAIL对应的属性值发送邮件
            case MQInterfaceType.SMS_MAIL:
                messageAdapter = smsMailboxService;		//确定调用邮件发送实现类
                break;
			//...
            default:
                break;
        }
        //获得消息体内容(mail和username)
        JSONObject content = jsonObject.getJSONObject("content");
        //调用适配器的distribute方法,传入这个消息体对象
        messageAdapter.distribute(content);
    }
}

7.接下来,一旦开启了这个服务,就会一直监听消息队列,一旦有消息对应的消费者,消息就会有序地被消费,自动运行 @JmsListener(destination = “”)下对应的方法:

消息消费者加了1,出队的消息也加了1
在这里插入图片描述
邮件也被发送出去了:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值