SpringBoot整合Email 邮件发送
在开发中,经常会碰到email邮件发送的场景 如发送验证码,向客户发送邮件等等。
今天,本项目将讲解通过Springboot 发送email 邮件 普通文本邮件 ,HTML内容板式邮件 ,包含静态资源邮件,以及带附件邮件。
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-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
邮件发送需要的配置
因为各大邮件都有其对应安全系统,不是项目中想用就可以用的,我们必须要拿到其对应的客户端授权码才行,拿到授权码,在项目中配置SMTP服务协议以及主机 配置账户 ,就可以在项目中使用各大邮件运营商进行发送邮件了
获取客户端授权码过程
由于国内使用163邮箱以及qq邮箱较多 ,获取步骤大同小异,本文仅以qq邮箱获取授权码过程为例:
获取QQ邮箱授权码
登陆qq邮箱后,点击设置 选择 账户选项向下拉选择开启POP3/SMTP 服务
点击开启也会进入验证 验证成功后即可看到自己qq邮箱的客户端授权码了
我们在拿到授权码后,就可以在我们Springboot工程中的配置文件 aplication.yml 或者properties文件中配置了
YML配置
spring:
mail:
#smtp服务主机 qq邮箱则为smtp.qq.com
host: smtp.qq.com
#服务协议
protocol: smtp
# 编码集
default-encoding: UTF-8
#发送邮件的账户
username: xxxxxxx@qq.com
#授权码
password: xxxxxx
test-connection: true
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
代码编写
下面开始Springboot项目中发送邮件的代码编写
其实也非常简单 ,Springboot已经给我们邮件发送进行了非常好的整合了,我们只需要注入邮件发送接口 调用其中的方法,就能轻松而愉悦的进行邮件发送了!
我们只需要在任意交由Spring管理的类(例如你的service层等)下注入以下接口即可
@Autowired
private JavaMailSender mailSender;
由于每一封邮件都有固定的内容 例如 收件人信息 邮件内容 邮件标题 那么我们充分利用java面向对象的特性,我们吧邮件发送抽取为一个对象
代码采用了lombok进行简化
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ToEmail implements Serializable {
/**
* 邮件接收方,可多人
*/
private String[] tos;
/**
* 邮件主题
*/
private String subject;
/**
* 邮件内容
*/
private String content;
}
肯定有人纳闷了,那么接收方有了,发送方呢?
发送一方,肯定就是我们自身拿到的授权码账号啊 ,我们获取账户客户端授权码其目的就是为了让代码代替我们自身邮箱 向其他邮箱发送信息而已。
获取发送方账户信息
@Value("${spring.mail.username}")
private String from;
统一说明: R 为我项目自定义的响应类,结合 RestController 或者Responsebody向前端返回统一的JSON格式数据
普通邮件发送
public R commonEmail(ToEmail toEmail) {
//创建简单邮件消息
SimpleMailMessage message = new SimpleMailMessage();
//谁发的
message.setFrom(from);
//谁要接收
message.setTo(toEmail.getTos());
//邮件标题
message.setSubject(toEmail.getSubject());
//邮件内容
message.setText(toEmail.getContent());
try {
mailSender.send(message);
return R.data(toEmail.getTos(), "发送普通邮件成功");
} catch (MailException e) {
e.printStackTrace();
return R.fail("普通邮件方失败");
}
HTML邮件发送
public R htmlEmail(ToEmail toEmail) throws MessagingException {
//创建一个MINE消息
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper minehelper = new MimeMessageHelper(message, true);
//谁发
minehelper.setFrom(from);
//谁要接收
minehelper.setTo(toEmail.getTos());
//邮件主题
minehelper.setSubject(toEmail.getSubject());
//邮件内容 true 表示带有附件或html
minehelper.setText(toEmail.getContent(), true);
try {
mailSender.send(message);
return R.data(toEmail.getTos() + toEmail.getContent(), "HTML邮件成功");
} catch (MailException e) {
e.printStackTrace();
return R.fail("HTML邮件失败");
}
}
测试类
@Test
public void testHtml() throws Exception {
String content = "<html>\n" +
"<body>\n" +
" <h1>这是Html格式邮件!,不信你看邮件,我字体比一般字体还要大</h1>\n" +
"</body>\n" +
"</html>";
toEmailService.htmlEmail(new ToEmail(new String[]{"xxxx@qq.com"},"Html邮件",content));
}
含静态资源邮件发送
public R staticEmail(ToEmail toEmail, MultipartFile multipartFile, String resId) {
//创建一个MINE消息
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//谁发
helper.setFrom(from);
//谁接收
helper.setTo(toEmail.getTos());
//邮件主题
helper.setSubject(toEmail.getSubject());
//邮件内容 true 表示带有附件或html
//邮件内容拼接
String content =
"<html><body><img width='250px' src=\'cid:" + resId + "\'>" + toEmail.getContent()
+ "</body></html>";
helper.setText(content, true);
//蒋 multpartfile 转为file
File multipartFileToFile = MultipartFileToFile(multipartFile);
FileSystemResource res = new FileSystemResource(multipartFileToFile);
//添加内联资源,一个id对应一个资源,最终通过id来找到该资源
helper.addInline(resId, res);
mailSender.send(message);
return R.data(toEmail.getTos() + toEmail.getContent(), "嵌入静态资源的邮件已经发送");
} catch (MessagingException e) {
return R.fail("嵌入静态资源的邮件发送失败");
}
}
因为我当前没有使用文件服务器嘛,并未使用文件上传的URL 而是直接向接口传的multipartFile文件对象,但是邮件需要的是File对象,所以我们这里需要将multipartFile 转为 File
将 multpartfile 转为file
private File MultipartFileToFile(MultipartFile multiFile) {
// 获取文件名
String fileName = multiFile.getOriginalFilename();
// 获取文件后缀
String prefix = fileName.substring(fileName.lastIndexOf("."));
// 若需要防止生成的临时文件重复,可以在文件名后添加随机码
try {
File file = File.createTempFile(fileName, prefix);
multiFile.transferTo(file);
return file;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
带附件邮件发送
public R enclosureEmail(ToEmail toEmail, MultipartFile multipartFile) {
//创建一个MINE消息
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//谁发
helper.setFrom(from);
//谁接收
helper.setTo(toEmail.getTos());
//邮件主题
helper.setSubject(toEmail.getSubject());
//邮件内容 true 表示带有附件或html
helper.setText(toEmail.getContent(), true);
File multipartFileToFile = MultipartFileToFile(multipartFile);
FileSystemResource file = new FileSystemResource(multipartFileToFile);
String filename = file.getFilename();
//添加附件
helper.addAttachment(filename, file);
mailSender.send(message);
return R.data(toEmail.getTos() + toEmail.getContent(), "附件邮件成功");
} catch (MessagingException e) {
e.printStackTrace();
return R.fail("附件邮件发送失败" + e.getMessage());
}
}
富文本邮件发送
public void htmlEmail() throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setFrom("159****2662@163.com");
mimeMessageHelper.setTo("****@qianxx.com");
mimeMessageHelper.setSubject("富文本邮件主题");
String html = "<html><body><h4>Hello,SpringBoot</h4><img src='cid:boot' /></body></html>";
mimeMessageHelper.setText(html, true);
// 设置内嵌元素 cid,第一个参数表示内联图片的标识符,第二个参数标识资源引用
mimeMessageHelper.addInline("boot", new ClassPathResource("public/images/boot.png"));
javaMailSender.send(mimeMessage);
}
Thymeleaf 模板 — email.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Email</title>
</head>
<body>
<img src='cid:boot'>
<h4><span th:text="${title}">Craig Walls</span> says... </h4>
<i><span th:text="${content}">Hello Boot!</span></i>
</body>
</html>
@RunWith(SpringRunner.class)
@SpringBootTest
public class ThymeleafApplicationTests {
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private SpringTemplateEngine templateEngine;
@Test
public void contextLoads() throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setFrom("159****2662@163.com");
mimeMessageHelper.setTo("****@qianxx.com");
mimeMessageHelper.setSubject("ThymeLeaf 模板邮件");
// 利用 Thymeleaf 模板构建 html 文本
Context ctx = new Context();
ctx.setVariable("title", "Craig Walls");
ctx.setVariable("content", "Hello Boot!");
String emailText = templateEngine.process("email/email", ctx);
mimeMessageHelper.setText(emailText, true);
// 设置内嵌元素 cid,第一个参数表示内联图片的标识符,第二个参数标识资源引用
mimeMessageHelper.addInline("boot", new ClassPathResource("/static/img/boot.png"));
javaMailSender.send(mimeMessage);
}
}