springboot整合邮件发送功能
Spring Boot整合了邮件服务器,使用Spring Boot能够轻松实现邮件发送,我这里以QQ邮箱为例。
springboot整合邮件发送功能
一、开启QQ邮箱服务
当我们需要在第三方客户端登录QQ邮箱时,就需要先开启QQ邮箱的POP3/SMTP服务,这样才能成功发出邮件。
1、首先,我们登录QQ邮箱,按下图步骤,点击设置,再点击账户,往下滑动,直到看到POP3/SMTP服务选项,如图:
2、一般情况下,QQ邮箱的【POP3/SMTP服务】初始设置是关闭状态,然后就需要我们手动开启,由于我之前开启过,所以我上图显示的是已开启状态。我这为了演示,点击关闭再重新开启一下。如图所示,点击开启时,需要发送短信到指定号码:
3、我们根据指示发送短信,如图:
4、回到电脑网页,点击【我已发送】,如图:
5、之后,我们就可以得到【授权码】。大家可以拿个记事本记下来,我们后面需要用到这个授权码。当然,遗忘了也没关系,跟着这个操作再走一遍就行。至此,准备工作就已经完成了。如图:
二、初始化项目
1、项目使用idea自带的springboot初始化器即可,或者使用maven工程也行。
首先,我们在pom文件里面添加一下依赖,这是我们后面要用到的。
完整pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.java</groupId>
<artifactId>springboot-mail</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-mail</name>
<description>springboot整合邮件发送功能</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 1、邮件推送模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- 2、hutool工具模块-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
<!-- 3、spring-web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 4、热部署模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 5、单元测试模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、编写配置文件,这里我们使用yml格式的配置文件,如图:
完整配置文件
# 端口号
server:
port: 8080
# 邮件发送配置
spring:
servlet:
# 限制附件上传大小
multipart:
enabled: true
max-file-size: 50MB
max-request-size: 50MB
# 发送email设置,以QQ邮箱为例
mail:
host: smtp.qq.com # 配置服务器 qq:smtp.qq.com,网易163:smtp.163.com
username: 1015390189@qq.com # 配置发件人
password: kxekbudkrewkbehf # 配置授权码,邮箱->设置->账户->POP3/SMTP服务:开启服务后会获得授权码
default-encoding: UTF-8 # 配置默认编码
properties: # 一些其他的配置
mail:
smtp:
ssl:
trust: mail.cmhk.com
timeout: 10000
connectiontimeout: 10000
writetimeout: 10000
auth: true
starttls:
enable: true
required: true
socketFactory:
class: javax.net.ssl.SSLSocketFactory
port: 465
三、发送简单邮件
我们编写一个测试类,实现发送简单邮件的功能,代码如下
完整代码:
package com.java.mail;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.internet.MimeMessage;
import java.io.File;
@SpringBootTest
class SpringbootMailApplicationTests {
@Autowired
private JavaMailSender javaMailSender;
@Test
void contextLoads() {
System.out.println(javaMailSender);
}
/**
* 发送一个简单邮件
*/
@Test
public void sendSimpleMail(){
//创建消息对象
SimpleMailMessage mailMessage=new SimpleMailMessage();
//设置发送人
mailMessage.setFrom("1015390189@qq.com");
//设置接收人
mailMessage.setTo("553272640@qq.com", "2833676233@qq.com");
//设置邮件标题
mailMessage.setSubject("使用springboot测试的简单邮件!");
//设置内容
mailMessage.setText("测试测试测试测试");
//发送邮件
javaMailSender.send(mailMessage);
System.out.println("发送成功");
}
}
代码执行完之后,稍等两秒接收方的两个QQ邮箱立马收到了发过来的邮件,同时能看到标题与正文,如图:
四、发送复杂邮件
我们编写一个测试类,实现发送复杂邮件的功能,包括正文附带图片以及可以携带附件,代码如下:
【记得附件地址及图片地址替换成自己本地的真实地址】
完整代码如下:【记得附件地址及图片地址替换成自己本地的真实地址】
package com.java.mail;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.internet.MimeMessage;
import java.io.File;
@SpringBootTest
class SpringbootMailApplicationTests {
@Autowired
private JavaMailSender javaMailSender;
@Test
void contextLoads() {
System.out.println(javaMailSender);
}
/**
* 发送一个复杂的邮件
*
*/
@Test
public void sendComplexMail() throws Exception{
//创建一个复杂的邮寄对象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//创建一个MimeMessageHelper,来组装参数 true表示开启附件,utf-8表示编码
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
//设置发送人
mimeMessageHelper.setFrom("1015390189@qq.com");
//设置接收人
String[] to ={"553272640@qq.com", "2833676233@qq.com"};
mimeMessageHelper.setTo(to);
//设置主题
mimeMessageHelper.setSubject("这是一个复杂的邮件,带html解析和附件的哦");
//拼接内容参数
StringBuilder sb = new StringBuilder();
sb.append("<html> <body> <h1 style='color:red'>springboot 测试邮件发送复杂格式o</h1>");
sb.append("<p style='color:blue,font-size:16px'>哈哈哈</p>");
sb.append("<p style='text-align:center'>居中</p>");
sb.append("<img src='cid:picture'/> </body></html>"); //如果要插入图片src='cid:picture',相当于占位符
//设置内容,可以被html解析
mimeMessageHelper.setText(sb.toString(), true);
//添加内容图片
mimeMessageHelper.addInline("picture", new File("F:\\06-图标库\\环球设计榜 Designer Emoji\\54_&Walsh_OhNo.png"));
//添加附件
mimeMessageHelper.addAttachment("统计图.zip", new File("F:\\01-其他文件夹\\echarts 多折线图.zip"));
// mimeMessageHelper.addInline("picture", new File("E:\\资料\\相关素材\\大图\\img5.jpg"));
// //添加附件
// mimeMessageHelper.addAttachment("大图.zip", new File("E:\\资料\\相关素材\\大图.zip"));
javaMailSender.send(mimeMessage);
System.out.println("发送成功!");
}
}
执行之后的截图:
五、远程调用邮箱接口发送复杂邮件
由于我们往往都是调用邮箱接口进行邮件发送的,写成一个测试类肯定不符合我们的实际需求,接下来我们写一个controller接口,然后通过调用接口来实现发送复杂邮件。
1、pom文件以及配置文件都跟上面的一样,不需要改动
2、新建一个util包,编写一个简单的返回json对象的通用类,代码如下:
package com.java.mail.util;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据通用类
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("code", 0);
put("msg", "success");
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R ok() {
return new R();
}
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
3、新建一个controller类,编写邮件发送接口,代码如下:
package com.java.mail.controller;
import com.java.mail.util.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* 描述: 邮件发送控制器
* </p>
* @author 10153
* @since 2021-03-30 09:36
*/
@RestController
@RequestMapping( "mail" )
public class MailController {
protected final static Logger logger = (Logger) LoggerFactory.getLogger(MailController.class);
@Autowired
private JavaMailSender javaMailSender;
/**
* 邮件发件人,从配置文件获取
*/
@Value( "${spring.mail.username}" )
private String sender;
/**
* @param formList 接收人列表
* @param title 邮件标题
* @param picture 正文图片
* @param zipName 附件名称
* @param attachment 附件
* @apiNote 发送复杂邮件,包括图片以及附件
* @since 2021/3/26 13:46
* @author qiugq
*/
@PostMapping( "sendComplexMail" )
public R sendComplexMail(@RequestParam( value = "formList" ) List<String> formList,
@RequestParam( value = "title" ) String title,
@RequestParam( value = "picture" ) MultipartFile picture,
@RequestParam(value = "zipName") String zipName,
@RequestParam(value = "attachment") MultipartFile attachment ) {
//创建一个复杂的邮寄对象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//创建一个MimeMessageHelper,来组装参数 true表示开启附件,utf-8表示编码
MimeMessageHelper mimeMessageHelper = null;
try {
mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
//1、设置发送人
mimeMessageHelper.setFrom(sender);
//2、设置接收人
String[] to = formList.toArray(new String[0]);
logger.info("输出收件人: " + Arrays.toString(to));
mimeMessageHelper.setTo(to);
//3、设置主题
mimeMessageHelper.setSubject(title);
//拼接内容参数
String sb = "<html><body> <img src='cid:picture'/> </body></html>";//如果要插入图片src='cid:picture',相当于占位符
//4、设置内容,可以被html解析
mimeMessageHelper.setText(sb, true);
// 上传文件名,原始文件名
String pictureName = picture.getOriginalFilename();
logger.info("输出正文图片: " + pictureName);
// 断言,为了避免空指针
assert pictureName != null;
// 将图片保存在本地
File dest = new File(System.getProperty("user.dir") + "/temp" + pictureName.substring(pictureName.lastIndexOf(".")));
picture.transferTo(dest);
if ( !dest.getParentFile().exists() ) {
if ( !dest.getParentFile().mkdirs() ) {
logger.error("生成图片目录失败!");
}
}
//5、添加内容图片
mimeMessageHelper.addInline("picture", dest);
//6、添加附件
logger.info("输出附件名称: " + zipName);
mimeMessageHelper.addAttachment(zipName, attachment);
// 7、发送邮件
javaMailSender.send(mimeMessage);
// 8、删除已保存的文件
if ( dest.delete() ) {
logger.info("删除正文图片成功");
} else {
logger.error("删除正文图片失败");
}
} catch ( MessagingException | IOException e ) {
logger.error("--------发送失败---------");
e.printStackTrace();
return R.error(-1,"发送失败");
}
return R.ok("发送成功");
}
}
4、编写一个测试类,调用这个邮件发送接口,代码如下:
package com.java.mail.test;
import cn.hutool.core.lang.Console;
import cn.hutool.http.HttpRequest;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* <p>
* 描述: 测试邮件发送
* </p>
* @author 10153
* @since 2021-03-26 14:43
*/
public class TestSendMail {
public static void main(String[] args) {
Map<String, Object> paramMap = new HashMap<>();
// 收件人
paramMap.put("formList", Arrays.asList("553272640@qq.com", "2833676233@qq.com"));
// 邮件标题
paramMap.put("title", "使用springboot调用第三方邮件接口");
// 正文图片
paramMap.put("picture", new File("F:\\06-图标库\\环球设计榜 Designer Emoji\\61_&Walsh_NewProject.png"));
// 附件名称
paramMap.put("zipName", "统计图.zip");
// 附件内容
paramMap.put("attachment", new File("F:\\01-其他文件夹\\echarts 多折线图.zip"));
// hutool工具类http请求
String result2 = HttpRequest.post("http://localhost:8080/mail/sendComplexMail")
.form(paramMap) //表单内容
.timeout(50000) // 超时,毫秒
.execute().body();
Console.log(result2);
}
}
5、项目的整体结构如图:
6、测试:
首先【启动springboot项目】,启动之后,再执行测试类,运行截图如下:
记得项目执行顺序不能错啊,我截图调整了顺序是为了大家能看到打印的一些信息!
【1、执行测试类截图】
【2、运行springboot项目,调用接口后打印信息截图】
【3、邮件接收成功的截图】
7、目前为止,调用接口进行邮件发送就已经实现了。
总结
本篇博文已经粘贴了该项目的全部代码,大家可以随意使用,但是,由于涉及到一些私人信息,比如QQ邮箱账号以及授权码等等。所以大家学习的时候,尽量把这个邮箱改成大家自己的邮箱账号,谢谢体谅。