首先,引入发送邮件的依赖,由于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. jquery.zclip.js复制到剪切板

    参考http://www.cnblogs.com/PeunZhang/p/3324727.html 需要引用jquery.zclip $("#id").zclip({ path: ...

  2. s2sh的MVC执行流程和执行原理

    =======================执行流程 1. 从页面开始,提交表单或者点击链接会触发一个action 2. action交给struts2处理,读取src目录struts.xml文件, ...

  3. angular自定义指令-directive

    Directive究竟是个怎么样的一个东西呢?我个人的理解是这样的:将一段html.js封装在一起,形成一个可复用的独立个体,具体特定的功能.下面我们来详细解读一下Directive的一般性用法. v ...

  4. 从url获取参数有中文时会出现乱码的问题

    http://192.168.1.133/v2?groupId=58&opFlag=1&result=C,B,B,B,D&Name=本人很帅 我们js获取的url中的Name其 ...

  5. 【WPF】这可能是全网最全的拖拽实现方法的总结

    原文地址 https://www.cnblogs.com/younShieh/p/10811456.html 前文 本文只对笔者学习掌握的一般的拖动问题的实现方法进行整理和讨论,包括窗口.控件等内容的 ...

  6. 如何让select中的滚动条自动定位到框中选中项的位置

    document.getElementById("hidScrollTop").value = document.getElementById("slcYZYongFa& ...

  7. web前端开发技术栈分析图

  8. C/C++中的段错误(Segmentation fault)[转]

    Segment fault 之所以能够流行于世,是与Glibc库中基本所有的函数都默认型参指针为非空有着密切关系的. 来自:http://oss.lzu.edu.cn/blog/article.php ...

  9. 挖一挖python中的深浅拷贝问题

    前几天在做面试题的时候,遇到一个与Python深浅拷贝的问题,今天总结出来一个方法,能够快速判断在对一个对象复制后,新对象与原来对象是否会互相影响的方法. 先抛出结论,然后我们对结论进行验证~~~ 先 ...

  10. js特效——自动滚动

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...