首先,引入发送邮件的依赖,由于freemarker自定义模板,所以也需要把freemarker的依赖引入

  pom.xml文件

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

  配置文件需要配置的信息:

spring.mail.host:smtp.qq.com
spring.mail.username:
spring.mail.password:
spring.mail.properties.mail.smtp.auth:true
spring.mail.properties.mail.debug:true

  使用qq邮箱需要开通POP3/SMTP服务,具体方法自行百度。

  实现轮询发送的类,这里主要就是将默认只保存一个用户的配置bean注入到本实例中,读取配置文件中的username和password,分割成多个用户和密码保存到队列中。重写doSend()方法实现轮询。具体代码如下:

package com.wangx.boot.mail;

import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl; import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.Map;
import java.util.Properties; /**
* 实现多账号,轮询发送
* @EnableConfigurationProperties注解将MailProperties这个保存邮件相关信息的bean注入到本类引用中
*/
@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class WangxJavaMailSenderImpl extends JavaMailSenderImpl implements JavaMailSender { //保存多个用户名和密码的队列
private ArrayList<String> usernameList;
private ArrayList<String> passwordList;
//轮询标识
private int currentMailId = 0; private final MailProperties properties; public WangxJavaMailSenderImpl(MailProperties properties) {
this.properties = properties; // 初始化账号
if (usernameList == null)
usernameList = new ArrayList<String>();
String[] userNames = this.properties.getUsername().split(",");
if (userNames != null) {
for (String user : userNames) {
usernameList.add(user);
}
} // 初始化密码
if (passwordList == null)
passwordList = new ArrayList<String>();
String[] passwords = this.properties.getPassword().split(",");
if (passwords != null) {
for (String pw : passwords) {
passwordList.add(pw);
}
}
} @Override
protected void doSend(MimeMessage[] mimeMessage, Object[] object) throws MailException { super.setUsername(usernameList.get(currentMailId));
super.setPassword(passwordList.get(currentMailId)); // 设置编码和各种参数
super.setHost(this.properties.getHost());
super.setDefaultEncoding(this.properties.getDefaultEncoding().name());
super.setJavaMailProperties(asProperties(this.properties.getProperties()));
super.doSend(mimeMessage, object); // 轮询
currentMailId = (currentMailId + 1) % usernameList.size();
} private Properties asProperties(Map<String, String> source) {
Properties properties = new Properties();
properties.putAll(source);
return properties;
} @Override
public String getUsername() {
return usernameList.get(currentMailId);
} }

  实现模板加入模板发送的方法,主要是先定义好模板,然后将模板解析成字符串,组装MimeMessage对象,调用JavaMailSenderImpl的send方法发送,具体实现代码如下

package com.wangx.boot.component;

import com.wangx.boot.mail.WangxJavaMailSenderImpl;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map; /**
*
*/
@Component
public class WangxJavaMailComponent {
private static final String template = "mail/wangx.ftl"; @Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Autowired
private WangxJavaMailSenderImpl wangxJavaMailSender; public void sendMail(String email) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("email", email);
try {
//获取解析到的模板的字符串
String text = getTextByTemplate(template, map);
send(email, text);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 解析模板文件,并将参数传入生成动态的字符串文返回
* @param template
* @param model
* @return
* @throws IOException
* @throws TemplateException
*/
private String getTextByTemplate(String template, Map<String, Object> model) throws IOException, TemplateException {
return FreeMarkerTemplateUtils.processTemplateIntoString(freeMarkerConfigurer.getConfiguration().getTemplate(template), model);
} /**
* 组装 MimeMessage 对象并调用wangxJavaMailSender的send方法发送,在send方法中会调用我们angxJavaMailSenderW中重写的doSend方法
* @param email
* @param text
* @return
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
private String send(String email, String text) throws MessagingException, UnsupportedEncodingException {
MimeMessage message = wangxJavaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
InternetAddress from = new InternetAddress();
from.setAddress(wangxJavaMailSender.getUsername());
from.setPersonal("Wangx", "UTF-8");
helper.setFrom(from);
helper.setTo(email);
helper.setSubject("测试邮件");
helper.setText(text, true);
wangxJavaMailSender.send(message);
return text;
} }

  测试发送的接口

package com.wangx.boot.controller;

import com.wangx.boot.component.WangxJavaMailComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/mail")
public class MailController { @Autowired
private WangxJavaMailComponent wangxJavaMailComponent;
@RequestMapping("/send")
@ResponseBody
public String send(String mail) {
wangxJavaMailComponent.sendMail(mail);
return "success";
}
}

  访问http://localhost:8080/mail/send?mail=要发送的邮箱 即可发送邮件到你制定的邮箱。

SpringBoot学习笔记(12)----SpringBoot实现多个 账号轮询发送邮件的更多相关文章

  1. SpringBoot学习笔记(6) SpringBoot数据缓存Cache [Guava和Redis实现]

    https://blog.csdn.net/a67474506/article/details/52608855 Spring定义了org.springframework.cache.CacheMan ...

  2. springboot学习笔记-5 springboot整合shiro

    shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/  它提供了很方便的权限认证和登录的功能. 而springboot作为一个开源框架,必然提供了和sh ...

  3. springboot学习笔记-6 springboot整合RabbitMQ

    一 RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿 ...

  4. 【转】SpringBoot学习笔记(7) SpringBoot整合Dubbo(使用yml配置)

    http://blog.csdn.net/a67474506/article/details/61640548 Dubbo是什么东西我这里就不详细介绍了,自己可以去谷歌 SpringBoot整合Dub ...

  5. SpringBoot学习笔记(16)----SpringBoot整合Swagger2

    Swagger 是一个规范和完整的框架,用于生成,描述,调用和可视化RESTful风格的web服务 http://swagger.io Springfox的前身是swagger-springmvc,是 ...

  6. SpringBoot学习笔记(15)----SpringBoot使用Druid

    直接访问Druid官网wiki,有详细教程,地址如下: SpringBoot支持Druid地址:https://github.com/alibaba/druid/tree/master/druid-s ...

  7. SpringBoot学习笔记(11)-----SpringBoot中使用rabbitmq,activemq消息队列和rest服务的调用

    1. activemq 首先引入依赖 pom.xml文件 <dependency> <groupId>org.springframework.boot</groupId& ...

  8. SpringBoot学习笔记(10)-----SpringBoot中使用Redis/Mongodb和缓存Ehcache缓存和redis缓存

    1. 使用Redis 在使用redis之前,首先要保证安装或有redis的服务器,接下就是引入redis依赖. pom.xml文件如下 <dependency> <groupId&g ...

  9. SpringBoot学习笔记(9)----SpringBoot中使用关系型数据库以及事务处理

    在实际的运用开发中,跟数据库之间的交互是必不可少的,SpringBoot也提供了两种跟数据库交互的方式. 1. 使用JdbcTemplate 在SpringBoot中提供了JdbcTemplate模板 ...

随机推荐

  1. python pip fatal error in launcher unable to create process using

    用pip安装一个包,不知道为啥,就报了这个错误:python pip fatal error in launcher unable to create process using “”   百度了一下 ...

  2. 性能优化实战-join与where条件执行顺序

    昨天经历了一场非常痛苦的性能调优过程,但是收获也是刻骨铭心的,感觉对sql引擎的原理有了进一步认识. 问题起源于测试人员测一个多条件检索的性能时,发现按某个条件查询会特别慢.对应的sql语句简化为: ...

  3. pgpool中的配置参数的定义

    /* * configuration parameters */typedef struct {    char *listen_addresses;            /* hostnames/ ...

  4. 【摘录】JAVA内存管理-自动选择垃圾收集器算法

    在J2SE 5.0,垃圾收集的默认值:垃圾收集器.堆大小以及JVM的类型(客户端还是服务器)都会根据应用运行的硬件平台和操作系统自动选择.相比之前设置命令行参数的方式,自动选择很好的匹配了不同类型的应 ...

  5. QA小课堂:一个网站或者APP开发要多少钱

    经常遇到朋友问我:“开发一个京东商城需要多少钱?开发一个滴滴打车需要多少钱?”类似这样的需求,就连我这样一名伪开发者都不愿意去骗客户或者朋友,因为这种问题是很难回答出来的.为什么这么说呢?要知道类似京 ...

  6. [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导

    p.s. 复合函数求导时千万不能先带值,再求导. 一定要先将符合函数按照求导的规则展开,再带值. 设 $f(x)=g(h(x))$,则对 $f(x)$ 求导: $f'(x)=h'(x)g'(h(x)) ...

  7. luoguP2742 【模板】二维凸包 / [USACO5.1]圈奶牛 二维凸包

    我们知道,纵坐标最小的点一定在凸包上(如果有多个,那它们都会被取到) 随便找一个纵坐标最小的点,将其他所有点按照这个点为原点极角排序,我们发现极角大的会在极角小的后面加入(感性认知一下) 考虑新(加入 ...

  8. Pyhton学习——Day29

    #异常与错误# 什么是异常?# 异常就是程序运行时发生错误的信号,在程序出现错误时,则会产生异常,若没有程序处理,则会抛出异常# 导致程序在异常语句处崩溃终止# Traceback 追踪异常信号:** ...

  9. elk集群配置配置文件中节点数配多少

    配置elk集群时,遇到,elasticsearch配置文件中的一个配置discovery.zen.minimum_master_nodes: 2.这里是三配的2 看到某一位的解释是这样:为了避免脑裂, ...

  10. 2019-03-18 OpenCV Tesseract-OCR 下载 安装 配置(cv2 报错)

    OpenCV 下载 安装 配置 1.下载和Python版本对应的版本,此为下载地址 2.安装(在powershell管理员模式下安装) pip3 install .\opencv_python-3.4 ...