Spring-Boot快速集成Java-Mail
说明
因为SpringBoot默认有starter实现了Mail。发送邮件应该是网站的必备功能之一,什么注册验证,忘记密码或者是给用户发送营销信息。最早期的时候我们会使用JavaMail相关api来写发送邮件的相关代码,后来spring推出了JavaMailSender更加简化了邮件发送的过程,在之后springboot对此进行了封装就有了现在的spring-boot-starter-mail。
Maven依赖
<!-- Mail组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
在Spring-Boot中引入spring-boot-starter-mail 的依赖就可以使用Java-Mail发送邮件。
thymeleaf模板的引入是为了,支持html内容的邮件发送。
# 邮箱配置
spring:
mail:
host: smtp.163.com
port: 25
username: medicialbbs@163.com
password: *********
protocol: smtp
default-encoding: utf-8
test-connection: true
配置默认邮箱的站点,端口,用户名,授权码,协议,默认编码,是否启用链接测试。
模式支持
- 支持文本邮件
- 支持html模板邮件
- 支持cc发送
- 支持链接文件
- 支持自定义邮箱配置
为了支持上述模式同时保证代码精简,我这里定义了MailContentBuilder的构造器去完成邮件内容和格式构造。
定义邮件内容构造器
package club.dlblog.mail.config;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.StringUtils;
import javax.mail.MessagingException;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* mail内容构造器
* @author machenike
*/
public class MailContentBuilder {
/**
* 内容
*/
private String content;
/**
* 接收者
*/
private String to;
/**
* 发送者
*/
private String from;
/**
* 主题
*/
private String subject;
/**
* cc
*/
private String[] cc;
/**
* 链接文件
*/
private Map<String, File> linkFiles;
/**
* 是否类型为html
*/
private boolean isHtml = false;
/**
* 构建content
* @param content
* @return
*/
public MailContentBuilder content(String content){
this.content = content;
return this;
}
public String content(){
return content;
}
/**
* 构建接收者
* @param to
* @return
*/
public MailContentBuilder to(String to){
this.to = to;
return this;
}
public String to(){
return to;
}
/**
* 构建发送者
* @param from
* @return
*/
public MailContentBuilder from(String from){
this.from = from;
return this;
}
public String from(){
return from;
}
/**
* 构建主题
* @param suject
* @return
*/
public MailContentBuilder subject(String suject){
this.subject =suject;
return this;
}
public String subject(){
return subject;
}
/**
* 构建cc
* @param cc
* @return
*/
public MailContentBuilder cc(String[] cc){
this.cc = cc;
return this;
}
public String[] cc(){
return cc;
}
/**
* 链接文件
* @param files
* @return
*/
public MailContentBuilder linkFiles(Map<String,File> files){
this.linkFiles = files;
return this;
}
public Map<String,File> linkFiles(){
return linkFiles;
}
/**
* 构建isHtml
* @param isHtml
* @return
*/
public MailContentBuilder isHtml(boolean isHtml){
this.isHtml = isHtml;
return this;
}
public boolean isHtml(){
return isHtml;
}
/**
* 私有化构造方法
*/
private MailContentBuilder(){
}
/**
* 实例对象获取方法
* @return
*/
public static MailContentBuilder getInstance(){
MailContentBuilder builder = new MailContentBuilder();
return builder;
}
/**
* 集成Helper,中间操作
* @param helper
*/
public void setInvocation(MimeMessageHelper helper){
try {
if(!StringUtils.isEmpty(from)){
helper.setFrom(from);
}
if(!StringUtils.isEmpty(to)){
helper.setTo(to);
}
if(!StringUtils.isEmpty(subject)){
helper.setSubject(subject);
}
if(!StringUtils.isEmpty(content)){
helper.setText(content, isHtml);
}
if(linkFiles!=null){
Set<String> keySet = linkFiles.keySet();
for (String key:keySet){
helper.addAttachment(key,linkFiles.get(key));
}
}
if(cc!=null&&cc.length>0){
helper.setCc(cc);
}
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
定义Mail发送接口,可见支持多种模式的邮件发送方法
package club.dlblog.mail.service;
import club.dlblog.mail.config.MailConfigBean;
import club.dlblog.mail.config.MailContentBuilder;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import java.io.File;
import java.util.Map;
/**
* MailServiceImpl 邮件发送服务实现类
* @author machenike
*/
public interface MailService {
/**
* 配置取得
* @return mail邮箱配置
*/
MailProperties getConfig();
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param text 文本内容
* @return true -成功 false -失败
*/
boolean send(String to, String subject, String text);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param text 文本内容
* @param linkFiles 链接文件
* @return true -成功 false -失败
*/
boolean send(String to, String subject, String text, Map<String, File > linkFiles);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param text 文本内容
* @param cc 邮件cc
* @return true -成功 false -失败
*/
boolean send(String to, String subject, String text,String[] cc);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param text 文本内容
* @param cc 邮件cc
* @param linkFiles 链接文件
* @return true -成功 false -失败
*/
boolean send(String to, String subject, String text,String[] cc,Map<String, File > linkFiles);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param params 模板参数
* @param template 模板文件
* @return true -成功 false -失败
*/
boolean send(String to, String subject, Map<String,Object> params, String template);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param params 模板参数
* @param template 模板文件
* @param linkFiles 链接文件
* @return true -成功 false -失败
*/
boolean send(String to, String subject, Map<String,Object> params, String template,Map<String, File > linkFiles);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param params 模板参数
* @param template 模板文件
* @param cc 邮件cc
* @return true -成功 false -失败
*/
boolean send(String to, String subject, Map<String,Object> params, String template,String[] cc);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param params 模板参数
* @param template 模板文件
* @param cc 邮件cc
* @param linkFiles 链接文件
* @return true -成功 false -失败
*/
boolean send(String to, String subject, Map<String,Object> params, String template,String[] cc,Map<String, File > linkFiles);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param text 文本内容
* @param configBean 邮箱配置
* @return true -成功 false -失败
*/
boolean send(String to, String subject, String text, MailConfigBean configBean);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param text 文本内容
* @param linkFiles 链接文件
* @param configBean 邮箱配置
* @return true -成功 false -失败
*/
boolean send(String to, String subject, String text,Map<String, File > linkFiles,MailConfigBean configBean);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param params 模板参数
* @param template 模板文件
* @param configBean 邮箱配置
* @return true -成功 false -失败
*/
boolean send(String to, String subject, Map<String,Object> params, String template,MailConfigBean configBean);
/**
* 邮件发送
* @param to 接收者
* @param subject 主题
* @param params 模板参数
* @param template 模板文件
* @param linkFiles 链接文件
* @param configBean 邮箱配置
* @return true -成功 false -失败
*/
boolean send(String to, String subject, Map<String,Object> params, String template,Map<String, File > linkFiles,MailConfigBean configBean);
/**
* 邮件发送
* @param builder 邮件内容构造器
* @return true -成功 false -失败
*/
boolean send(MailContentBuilder builder);
/**
* 邮件发送
* @param builder 邮件内容构造器
* @param configBean 邮件配置
* @return true -成功 false -失败
*/
boolean send(MailContentBuilder builder,MailConfigBean configBean);
}
MailServer接口实现
邮件发送完全基于JavaMailSender的实现类JavaMailSenderImpl
@Override
public boolean send(String to, String subject, Map<String, Object> params, String template, Map<String, File> linkFiles, MailConfigBean configBean) {
boolean sendResult;
//取得模板内容
String emailContent = getTemplateContent(template,params);
//构造邮件内容
MailContentBuilder builder = MailContentBuilder.getInstance()
.to(to).from(from).subject(subject).content(emailContent).linkFiles(linkFiles);
sendResult = this.send(builder,configBean);
return sendResult;
}
@Override
public boolean send(MailContentBuilder builder) {
boolean result = true;
try {
//构造message
MimeMessage message = mailSender.createMimeMessage();
//取得MessaeHelper
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//拦截预处理
builder.setInvocation(helper);
mailSender.send(message);
} catch (Throwable e) {
e.printStackTrace();
result =false;
}
return result;
}
@Override
public boolean send(MailContentBuilder builder, MailConfigBean configBean) {
JavaMailSenderImpl sender = null;
boolean result = true;
try {
//构造sender
sender = getMailSender(configBean);
} catch (IllegalAccessException e) {
e.printStackTrace();
result =false;
} catch (NoSuchFieldException e) {
e.printStackTrace();
result =false;
}
try {
//构造message
MimeMessage message = sender.createMimeMessage();
//取得MessaeHelper
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//拦截预处理
builder.setInvocation(helper);
sender.send(message);
} catch (Throwable e) {
e.printStackTrace();
result =false;
}
return result;
}
/**
* 通过html模板生成邮件内容
* @param template 模板文件
* @param params 模板参数
* @return 模板解析完了内容
*/
private String getTemplateContent(String template,Map<String,Object> params){
//初始化模板上下文
Context context = new Context();
//设定模板参数
context.setVariables(params);
//取得模板内容
String emailContent = templateEngine.process(template, context);
return emailContent;
}
/**
* 通过配置取得邮件sender
* @param configBean 邮箱配置
* @return 邮件发送器
* @throws IllegalAccessException 非法访问异常
* @throws NoSuchFieldException 字段不存在异常
*/
private JavaMailSenderImpl getMailSender(MailConfigBean configBean) throws IllegalAccessException, NoSuchFieldException {
//初始化邮件发射器实现类
JavaMailSenderImpl newSender = new JavaMailSenderImpl();
//字段取出
Field[] fields = configBean.getClass().getFields();
//迭代字段
for ( Field field:fields){
//设定允许访问
field.setAccessible(true);
//字段取得
Field tmpField = JavaMailSenderImpl.class.getField(field.getName());
//设定允许访问
tmpField.setAccessible(true);
//发送器设定
tmpField.set(newSender,field.get(configBean));
}
return newSender;
}
常见的邮件发送模式和功能都支持,spring-boot即插即用