SpringBoot+RabbitMQ实现邮箱服务

由于我有两个项目,每个项目都需要用到邮件,所以把邮件拆分出来做成了一个单独的邮件服务,也方便以后的项目直接调用。

也就是现在有三个服务,服务A接收其他服务发送的消息,这个消息中会包含三个基本的信息,邮件标题、邮件内容、接收者的邮件号。服务B、C发送包含这三个信息的消息到服务A中,服务A拿到信息后最终发送邮件。
在这里插入图片描述

一、安装RabbitMQ

我的系统是Linux(Deepin),Windows的就不演示了,只需要以下三条命令。

RabbitMq需要erlang语言的支持,在安装RabbitMq之前需要安装erlang。

apt-get install erlang-nox

接着安装RabbitMQ

apt-get install rabbitmq-server

如果需要Web端可视化操作界面,还需要配置Management Plugin插件。

rabbitmq-plugins enable rabbitmq_management

安装成功后输入地址http://127.0.0.1:15672/进行登录,默认账号密码都为guest。

账号和密码可以到Web控制台去添加,也可以用RabbitMq的命令添加(rabbitmqctl add_user 用户名 密码)。如果RabbitMq在云服务器上,除了要开放端口,还要开启远程访问功能,处于安全的考虑,guest这个默认的用户只能通过http://localhost:15672 来登录,其他的IP无法直接使用这个账号。
在这里插入图片描述
在这里插入图片描述

二、获取邮箱授权码

这里演示获取QQ邮箱的授权码,163大致也一样,不过经测试,发现在使用163发送大量邮件后,过段时间再次发送就会都被标为垃圾邮件,系统拒绝发送。这里可能是我内容的原因(恩…所有内容大致都一样,只是个别话不同),但使用QQ时只是偶尔发不出去。

登录QQ邮箱后,点击设置—账号。
在这里插入图片描述
然后开启POP3/SMTP服务,默认是关闭的。
在这里插入图片描述
点击下面生成授权码,在发送短信校验后会给你一串字符,要保存好。
在这里插入图片描述

三、Spring Boot配置邮箱和RabbitMq

首先添加依赖

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-mail</artifactId>
     <version>2.1.6.RELEASE</version>
 </dependency>
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-amqp</artifactId>
     <version>2.2.6.RELEASE</version>
 </dependency>

在配置application.properties。
spring.mail.username是你的邮箱号,spring.mail.password为上面生成的授权码。这里如果要用163,需要把host改成smtp.163.com。

spring.mail.host=smtp.qq.com
spring.mail.username=XXXXXXX@qq.com
spring.mail.password=上面生成的授权码
spring.mail.port=465
spring.mail.protocol=smtp
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.imap.ssl.socketFactory.fallback=false
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

RabbitMq配置,host为主机地址。最下面设置的消息接收确认模式,这里设置的手动确认。

spring.rabbitmq.host=ip地址
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

spring.rabbitmq.listener.simple.acknowledge-mode=manual

四、接收其他服务发送的消息

首先定义一个消息实体,其他服务自然也要发送这个实体到消息接受者上。

public class EmailInfo implements Serializable {
    private static final long serialVersionUID=1L;
    /**
     * 消息标题
     */
    private String title;
    /**
     * 消息内容
     */
    private String msg;
    /**
     * 接收者的邮箱号列表
     */
    private List<String> sendTo;
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public List<String> getSendTo() {
        return sendTo;
    }
    public void setSendTo(List<String> sendTo) {
        this.sendTo = sendTo;
    }
    public EmailInfo(String title, String msg, List<String> sendTo) {
        this.title = title;
        this.msg = msg;
        this.sendTo = sendTo;
    }
    public EmailInfo() {
    }
    @Override
    public String toString() {
        return "EmailInfo{" +
                "title='" + title + '\'' +
                ", msg='" + msg + '\'' +
                ", sendTo='" + sendTo + '\'' +
                '}';
    }
}

下面是消息接收。@RabbitListener注解可以直接创建交换器、队列、路由建,并且绑定。当这个队列中有消息时,会直接到process方法中处理,至于交换器和队列等概念在以后的文章中介绍或者自行学习, 使用 @Payload 和 @Headers 注解可以拿到消息中 body和headers 信息,也可以使用@Header获取单个 Header 属性,channel.basicAck方法为手动确认接收消息。

@Component
public class EmailReceiver {
    @Autowired
    JavaMailSender javaMailSender;
    @RabbitHandler
    @RabbitListener(
            bindings = @QueueBinding(
            value = @Queue(value = "email-queue",durable = "true"),
            exchange = @Exchange(name = "email-exchange",durable = "true",type = "topic"),
            key = "email.*"
    ))
    public void process(@Payload EmailInfo emailInfo,
                        @Headers Map<String,Object> header, Channel channel)  {
        Long tag =(Long) header.get(AmqpHeaders.DELIVERY_TAG);
        try {
            sendEmail(emailInfo);
            channel.basicAck(tag,false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void sendEmail(EmailInfo info){
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom("邮箱号");
            java.lang.String[] strings = info.getSendTo().toArray(new String[]{});
            message.setTo(strings);
            message.setSubject(info.getTitle());
            message.setText(info.getMsg());
            javaMailSender.send(message);
        }catch (Exception e){
            System.out.println("发送失败"+e.getMessage());
        }
    }
}

五、其他服务投递消息

在其他服务中同样需要添加依赖,并且在application.properties配置RabbitMq,可参考上面。

发送消息就比较简单了,如下。

@Autowired
private AmqpTemplate amqpTemplate;
public  void sendMail(String title,String msg,List<String> info){
    EmailInfo emailInfo = new EmailInfo(title, msg, info);
    amqpTemplate.convertAndSend("email-exchange","email.send",emailInfo);
}

六、测试

@RestController
public class RabbitContriller {
    @Autowired
    private AmqpTemplate amqpTemplate;
    public  void sendMail(String title,String msg,List<String> info){
        EmailInfo emailInfo = new EmailInfo(title, msg, info);
        amqpTemplate.convertAndSend("email-exchange","email.send",emailInfo);
    }
    @GetMapping("sendMq")
    public String send(){
        String context = "简单消息发送";
        EmailInfo emailInfo = new EmailInfo("标题", context, Arrays.asList("2606710413@qq.com"));
        amqpTemplate.convertAndSend("email-exchange","email.send",emailInfo);
        return "发送成功";
    }
}

访问这个地址后,不出意外,会收到此邮件。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值