@@ -0,0 +1,255 @@ | |||||
## spring-boot-demo-email | |||||
> 此 demo 主要演示了 Spring Boot 如何整合邮件功能,包括发送简单文本邮件、HTML邮件(包括模板HTML邮件)、附件邮件、静态资源邮件。 | |||||
### 1.开发步骤 | |||||
#### 1.1.添加依赖 | |||||
```xml | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>common-tools</artifactId> | |||||
</dependency> | |||||
<!-- Spring Boot 邮件依赖 --> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-mail</artifactId> | |||||
</dependency> | |||||
<!-- jasypt配置文件加解密 --> | |||||
<dependency> | |||||
<groupId>com.github.ulisesbocchio</groupId> | |||||
<artifactId>jasypt-spring-boot-starter</artifactId> | |||||
<version>${jasypt.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-test</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<!-- Spring Boot 模板依赖 --> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
``` | |||||
#### 1.2.添加邮件相关配置 | |||||
```yaml | |||||
spring: | |||||
mail: | |||||
host: smtp.mxhichina.com | |||||
port: 465 | |||||
from: "SpringBootDemo测试<${spring.mail.username}>" | |||||
username: spring-boot-demo@xkcoding.com | |||||
# 使用 jasypt 加密密码,使用com.xkcoding.email.PasswordTest.testGeneratePassword 生成加密密码,替换 ENC(加密密码) | |||||
password: ENC(aef0+nM5440HO7YFAo7iUz8ZHpkjZVlR0hNw3OI/QOPSkNhYRImE/Oy1LBgFKoB1OjqW0v4ZdM0xNS0eKxELfA==) | |||||
protocol: smtp | |||||
test-connection: true | |||||
default-encoding: UTF-8 | |||||
properties: | |||||
mail.smtp.auth: true | |||||
mail.smtp.starttls.enable: true | |||||
mail.smtp.starttls.required: true | |||||
mail.smtp.ssl.enable: true | |||||
mail.display.sendmail: spring-boot-demo | |||||
# 为 jasypt 配置解密秘钥 | |||||
jasypt: | |||||
encryptor: | |||||
password: spring-boot-demo | |||||
``` | |||||
#### 1.3.编写发送邮件代码 | |||||
- **抽象邮件服务接口**,方便后期替换不同的客户端实现 | |||||
```java | |||||
public interface MailService { | |||||
/** | |||||
* 发送文本邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
*/ | |||||
void sendSimpleMail(String to, String subject, String content, String... cc); | |||||
/** | |||||
* 发送HTML邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
void sendHtmlMail(String to, String subject, String content, String... cc) | |||||
throws MessagingException, MessagingException; | |||||
/** | |||||
* 发送带附件的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param filePath 附件地址 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) | |||||
throws MessagingException; | |||||
/** | |||||
* 发送正文中有静态资源的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param rscPath 静态资源地址 | |||||
* @param rscId 静态资源id | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) | |||||
throws MessagingException; | |||||
``` | |||||
- 接口实现 | |||||
```java | |||||
@Service | |||||
public class MailServiceImpl implements MailService { | |||||
@Autowired | |||||
private JavaMailSender mailSender; | |||||
@Value("${spring.mail.from}") | |||||
private String from; | |||||
/** | |||||
* 发送文本邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
*/ | |||||
@Override | |||||
public void sendSimpleMail(String to, String subject, String content, String... cc) { | |||||
SimpleMailMessage message = new SimpleMailMessage(); | |||||
message.setFrom(from); | |||||
message.setTo(to); | |||||
message.setSubject(subject); | |||||
message.setText(content); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
message.setCc(cc); | |||||
} | |||||
mailSender.send(message); | |||||
} | |||||
/** | |||||
* 发送HTML邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
*/ | |||||
@Override | |||||
public void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException { | |||||
MimeEmail mimeEmail = basicMimeEmailBuilder(to, subject, content, cc); | |||||
mailSender.send(mimeEmail.message()); | |||||
} | |||||
/** | |||||
* 发送带附件的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param filePath 附件地址 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
@Override | |||||
public void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) | |||||
throws MessagingException { | |||||
MimeEmail mimeEmail = basicMimeEmailBuilder(to, subject, content, cc); | |||||
MimeMessageHelper helper = mimeEmail.helper(); | |||||
FileSystemResource file = new FileSystemResource(new File(filePath)); | |||||
String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); | |||||
helper.addAttachment(fileName, file); | |||||
mailSender.send(mimeEmail.message()); | |||||
} | |||||
/** | |||||
* 发送正文中有静态资源的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param rscPath 静态资源地址 | |||||
* @param rscId 静态资源id | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
@Override | |||||
public void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) | |||||
throws MessagingException { | |||||
MimeEmail mimeEmail = basicMimeEmailBuilder(to, subject, content, cc); | |||||
MimeMessageHelper helper = mimeEmail.helper(); | |||||
FileSystemResource res = new FileSystemResource(new File(rscPath)); | |||||
helper.addInline(rscId, res); | |||||
mailSender.send(mimeEmail.message()); | |||||
} | |||||
/** | |||||
* 富文本邮件构造器,抽取重复代码,返回一个 MimeEmail record | |||||
*/ | |||||
private MimeEmail basicMimeEmailBuilder(String to, String subject, String content, String... cc) | |||||
throws MessagingException { | |||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | |||||
helper.setFrom(from); | |||||
helper.setTo(to); | |||||
helper.setSubject(subject); | |||||
helper.setText(content, true); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
helper.setCc(cc); | |||||
} | |||||
return new MimeEmail(message, helper); | |||||
} | |||||
private record MimeEmail(MimeMessage message, MimeMessageHelper helper) { | |||||
} | |||||
} | |||||
``` | |||||
- 其他资源文件参考 `classpath://resources` 目录 | |||||
### 2.测试 | |||||
参考 `MailServiceTest` 测试用例,分别运行各个方法,进行邮件测试 | |||||
> 注意: | |||||
> 1. 最好是每个方法分别运行,不要直接在测试类上一下跑所有测试用例,因为 Spring 的 `templateResolver` 一旦初始化是不允许修改的 | |||||
> 2. **强烈建议各位同学测试的时候,把邮箱改成自己的邮箱进行测试,这样才能实际体会到收到的邮件内容** | |||||
> 3. 请勿将 `spring-boot-demo@xkcoding.com` 的邮箱用于发送违法内容,否则作者将收回邮箱权限,同时提交给公安依法追究 | |||||
### 3.参考 | |||||
- Spring Boot 官方文档:https://docs.spring.io/spring-boot/docs/3.0.0-M4/reference/htmlsingle/#io.email | |||||
- Spring 官方文档:https://docs.spring.io/spring-framework/docs/6.0.0-M5/reference/html/integration.html#mail | |||||
- jasypt 加解密文档:https://github.com/ulisesbocchio/jasypt-spring-boot#what-to-do-first |
@@ -1,36 +1,40 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | <?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" | <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>demo-base</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
</parent> | |||||
<modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
<artifactId>demo-email</artifactId> | |||||
<artifactId>demo-base-email</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | <version>1.0.0-SNAPSHOT</version> | ||||
<packaging>jar</packaging> | <packaging>jar</packaging> | ||||
<name>demo-email</name> | |||||
<name>demo-base-email</name> | |||||
<description>Demo project for Spring Boot</description> | <description>Demo project for Spring Boot</description> | ||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
</parent> | |||||
<properties> | <properties> | ||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
<java.version>1.8</java.version> | |||||
<jasypt.version>2.1.1</jasypt.version> | |||||
<java.version>17</java.version> | |||||
<jasypt.version>3.0.4</jasypt.version> | |||||
</properties> | </properties> | ||||
<dependencies> | <dependencies> | ||||
<dependency> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>common-tools</artifactId> | |||||
</dependency> | |||||
<!-- Spring Boot 邮件依赖 --> | <!-- Spring Boot 邮件依赖 --> | ||||
<dependency> | <dependency> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
<artifactId>spring-boot-starter-mail</artifactId> | <artifactId>spring-boot-starter-mail</artifactId> | ||||
</dependency> | </dependency> | ||||
<!--jasypt配置文件加解密--> | |||||
<!-- jasypt配置文件加解密 --> | |||||
<dependency> | <dependency> | ||||
<groupId>com.github.ulisesbocchio</groupId> | <groupId>com.github.ulisesbocchio</groupId> | ||||
<artifactId>jasypt-spring-boot-starter</artifactId> | <artifactId>jasypt-spring-boot-starter</artifactId> | ||||
@@ -43,11 +47,6 @@ | |||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>cn.hutool</groupId> | |||||
<artifactId>hutool-all</artifactId> | |||||
</dependency> | |||||
<!-- Spring Boot 模板依赖 --> | <!-- Spring Boot 模板依赖 --> | ||||
<dependency> | <dependency> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
@@ -56,7 +55,7 @@ | |||||
</dependencies> | </dependencies> | ||||
<build> | <build> | ||||
<finalName>demo-email</finalName> | |||||
<finalName>demo-base-email</finalName> | |||||
<plugins> | <plugins> | ||||
<plugin> | <plugin> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> |
@@ -12,9 +12,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
* @date Created in 2018-11-04 22:38 | * @date Created in 2018-11-04 22:38 | ||||
*/ | */ | ||||
@SpringBootApplication | @SpringBootApplication | ||||
public class SpringBootDemoEmailApplication { | |||||
public class EmailApplication { | |||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
SpringApplication.run(SpringBootDemoEmailApplication.class, args); | |||||
SpringApplication.run(EmailApplication.class, args); | |||||
} | } | ||||
} | } |
@@ -1,6 +1,6 @@ | |||||
package com.xkcoding.email.service; | package com.xkcoding.email.service; | ||||
import javax.mail.MessagingException; | |||||
import jakarta.mail.MessagingException; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -30,7 +30,7 @@ public interface MailService { | |||||
* @param cc 抄送地址 | * @param cc 抄送地址 | ||||
* @throws MessagingException 邮件发送异常 | * @throws MessagingException 邮件发送异常 | ||||
*/ | */ | ||||
void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException; | |||||
void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException, MessagingException; | |||||
/** | /** | ||||
* 发送带附件的邮件 | * 发送带附件的邮件 |
@@ -2,6 +2,8 @@ package com.xkcoding.email.service.impl; | |||||
import cn.hutool.core.util.ArrayUtil; | import cn.hutool.core.util.ArrayUtil; | ||||
import com.xkcoding.email.service.MailService; | import com.xkcoding.email.service.MailService; | ||||
import jakarta.mail.MessagingException; | |||||
import jakarta.mail.internet.MimeMessage; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
import org.springframework.core.io.FileSystemResource; | import org.springframework.core.io.FileSystemResource; | ||||
@@ -10,8 +12,6 @@ import org.springframework.mail.javamail.JavaMailSender; | |||||
import org.springframework.mail.javamail.MimeMessageHelper; | import org.springframework.mail.javamail.MimeMessageHelper; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import javax.mail.MessagingException; | |||||
import javax.mail.internet.MimeMessage; | |||||
import java.io.File; | import java.io.File; | ||||
/** | /** | ||||
@@ -26,7 +26,7 @@ import java.io.File; | |||||
public class MailServiceImpl implements MailService { | public class MailServiceImpl implements MailService { | ||||
@Autowired | @Autowired | ||||
private JavaMailSender mailSender; | private JavaMailSender mailSender; | ||||
@Value("${spring.mail.username}") | |||||
@Value("${spring.mail.from}") | |||||
private String from; | private String from; | ||||
/** | /** | ||||
@@ -57,20 +57,11 @@ public class MailServiceImpl implements MailService { | |||||
* @param subject 邮件主题 | * @param subject 邮件主题 | ||||
* @param content 邮件内容 | * @param content 邮件内容 | ||||
* @param cc 抄送地址 | * @param cc 抄送地址 | ||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | */ | ||||
@Override | @Override | ||||
public void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException { | public void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException { | ||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | |||||
helper.setFrom(from); | |||||
helper.setTo(to); | |||||
helper.setSubject(subject); | |||||
helper.setText(content, true); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
helper.setCc(cc); | |||||
} | |||||
mailSender.send(message); | |||||
MimeEmail mimeEmail = basicMimeEmailBuilder(to, subject, content, cc); | |||||
mailSender.send(mimeEmail.message()); | |||||
} | } | ||||
/** | /** | ||||
@@ -85,21 +76,14 @@ public class MailServiceImpl implements MailService { | |||||
*/ | */ | ||||
@Override | @Override | ||||
public void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) throws MessagingException { | public void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) throws MessagingException { | ||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeEmail mimeEmail = basicMimeEmailBuilder(to, subject, content, cc); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | |||||
helper.setFrom(from); | |||||
helper.setTo(to); | |||||
helper.setSubject(subject); | |||||
helper.setText(content, true); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
helper.setCc(cc); | |||||
} | |||||
MimeMessageHelper helper = mimeEmail.helper(); | |||||
FileSystemResource file = new FileSystemResource(new File(filePath)); | FileSystemResource file = new FileSystemResource(new File(filePath)); | ||||
String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); | String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); | ||||
helper.addAttachment(fileName, file); | helper.addAttachment(fileName, file); | ||||
mailSender.send(message); | |||||
mailSender.send(mimeEmail.message()); | |||||
} | } | ||||
/** | /** | ||||
@@ -114,9 +98,22 @@ public class MailServiceImpl implements MailService { | |||||
* @throws MessagingException 邮件发送异常 | * @throws MessagingException 邮件发送异常 | ||||
*/ | */ | ||||
@Override | @Override | ||||
public void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) throws MessagingException { | |||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
public void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) | |||||
throws MessagingException { | |||||
MimeEmail mimeEmail = basicMimeEmailBuilder(to, subject, content, cc); | |||||
MimeMessageHelper helper = mimeEmail.helper(); | |||||
FileSystemResource res = new FileSystemResource(new File(rscPath)); | |||||
helper.addInline(rscId, res); | |||||
mailSender.send(mimeEmail.message()); | |||||
} | |||||
/** | |||||
* 富文本邮件构造器,抽取重复代码,返回一个 MimeEmail record | |||||
*/ | |||||
private MimeEmail basicMimeEmailBuilder(String to, String subject, String content, String... cc) throws MessagingException { | |||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | MimeMessageHelper helper = new MimeMessageHelper(message, true); | ||||
helper.setFrom(from); | helper.setFrom(from); | ||||
helper.setTo(to); | helper.setTo(to); | ||||
@@ -125,9 +122,10 @@ public class MailServiceImpl implements MailService { | |||||
if (ArrayUtil.isNotEmpty(cc)) { | if (ArrayUtil.isNotEmpty(cc)) { | ||||
helper.setCc(cc); | helper.setCc(cc); | ||||
} | } | ||||
FileSystemResource res = new FileSystemResource(new File(rscPath)); | |||||
helper.addInline(rscId, res); | |||||
return new MimeEmail(message, helper); | |||||
} | |||||
private record MimeEmail(MimeMessage message, MimeMessageHelper helper) { | |||||
mailSender.send(message); | |||||
} | } | ||||
} | } |
@@ -2,9 +2,10 @@ spring: | |||||
mail: | mail: | ||||
host: smtp.mxhichina.com | host: smtp.mxhichina.com | ||||
port: 465 | port: 465 | ||||
from: "SpringBootDemo测试<${spring.mail.username}>" | |||||
username: spring-boot-demo@xkcoding.com | username: spring-boot-demo@xkcoding.com | ||||
# 使用 jasypt 加密密码,使用com.xkcoding.email.PasswordTest.testGeneratePassword 生成加密密码,替换 ENC(加密密码) | |||||
password: ENC(OT0qGOpXrr1Iog1W+fjOiIDCJdBjHyhy) | |||||
# 使用 jasypt 加密密码,使用com.xkcoding.email.PasswordTest.testGeneratePassword 生成加密密码,替换 ENC(加密密码) | |||||
password: ENC(aef0+nM5440HO7YFAo7iUz8ZHpkjZVlR0hNw3OI/QOPSkNhYRImE/Oy1LBgFKoB1OjqW0v4ZdM0xNS0eKxELfA==) | |||||
protocol: smtp | protocol: smtp | ||||
test-connection: true | test-connection: true | ||||
default-encoding: UTF-8 | default-encoding: UTF-8 |
@@ -0,0 +1,13 @@ | |||||
package com.xkcoding.email; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
@SpringBootTest | |||||
class EmailApplicationTests { | |||||
@Test | |||||
void contextLoads() { | |||||
} | |||||
} |
@@ -1,8 +1,9 @@ | |||||
package com.xkcoding.email; | package com.xkcoding.email; | ||||
import org.jasypt.encryption.StringEncryptor; | import org.jasypt.encryption.StringEncryptor; | ||||
import org.junit.Test; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -12,7 +13,8 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||
* @author yangkai.shen | * @author yangkai.shen | ||||
* @date Created in 2019-08-27 16:15 | * @date Created in 2019-08-27 16:15 | ||||
*/ | */ | ||||
public class PasswordTest extends SpringBootDemoEmailApplicationTests { | |||||
@SpringBootTest | |||||
class PasswordTest { | |||||
@Autowired | @Autowired | ||||
private StringEncryptor encryptor; | private StringEncryptor encryptor; | ||||
@@ -20,7 +22,7 @@ public class PasswordTest extends SpringBootDemoEmailApplicationTests { | |||||
* 生成加密密码 | * 生成加密密码 | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void testGeneratePassword() { | |||||
void testGeneratePassword() { | |||||
// 你的邮箱密码 | // 你的邮箱密码 | ||||
String password = "Just4Test!"; | String password = "Just4Test!"; | ||||
// 加密后的密码(注意:配置上去的时候需要加 ENC(加密密码)) | // 加密后的密码(注意:配置上去的时候需要加 ENC(加密密码)) |
@@ -1,15 +1,16 @@ | |||||
package com.xkcoding.email.service; | package com.xkcoding.email.service; | ||||
import cn.hutool.core.io.resource.ResourceUtil; | import cn.hutool.core.io.resource.ResourceUtil; | ||||
import com.xkcoding.email.SpringBootDemoEmailApplicationTests; | |||||
import org.junit.Test; | |||||
import com.xkcoding.email.EmailApplication; | |||||
import jakarta.mail.MessagingException; | |||||
import org.junit.jupiter.api.Test; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.context.ApplicationContext; | import org.springframework.context.ApplicationContext; | ||||
import org.thymeleaf.TemplateEngine; | import org.thymeleaf.TemplateEngine; | ||||
import org.thymeleaf.context.Context; | import org.thymeleaf.context.Context; | ||||
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; | |||||
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver; | |||||
import javax.mail.MessagingException; | |||||
import java.net.URL; | import java.net.URL; | ||||
/** | /** | ||||
@@ -20,7 +21,8 @@ import java.net.URL; | |||||
* @author yangkai.shen | * @author yangkai.shen | ||||
* @date Created in 2018-11-21 13:49 | * @date Created in 2018-11-21 13:49 | ||||
*/ | */ | ||||
public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
@SpringBootTest(classes = EmailApplication.class) | |||||
class MailServiceTest { | |||||
@Autowired | @Autowired | ||||
private MailService mailService; | private MailService mailService; | ||||
@Autowired | @Autowired | ||||
@@ -37,19 +39,19 @@ public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
} | } | ||||
/** | /** | ||||
* 测试HTML邮件 | |||||
* 测试HTML邮件(使用 classpath://templates/ 下的模板) | |||||
* | * | ||||
* @throws MessagingException 邮件异常 | * @throws MessagingException 邮件异常 | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void sendHtmlMail() throws MessagingException { | |||||
Context context = new Context(); | |||||
context.setVariable("project", "Spring Boot Demo"); | |||||
context.setVariable("author", "Yangkai.Shen"); | |||||
context.setVariable("url", "https://github.com/xkcoding/spring-boot-demo"); | |||||
void sendHtmlMail1() throws MessagingException { | |||||
Context varContext = new Context(); | |||||
varContext.setVariable("project", "Spring Boot Demo"); | |||||
varContext.setVariable("author", "Yangkai.Shen"); | |||||
varContext.setVariable("url", "https://github.com/xkcoding/spring-boot-demo"); | |||||
String emailTemplate = templateEngine.process("welcome", context); | |||||
mailService.sendHtmlMail("237497819@qq.com", "这是一封模板HTML邮件", emailTemplate); | |||||
String emailTemplate = templateEngine.process("welcome", varContext); | |||||
mailService.sendHtmlMail("237497819@qq.com", "这是一封模板HTML邮件(templates目录)", emailTemplate); | |||||
} | } | ||||
/** | /** | ||||
@@ -58,7 +60,7 @@ public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
* @throws MessagingException 邮件异常 | * @throws MessagingException 邮件异常 | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void sendHtmlMail2() throws MessagingException { | |||||
void sendHtmlMail2() throws MessagingException { | |||||
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); | SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); | ||||
templateResolver.setApplicationContext(context); | templateResolver.setApplicationContext(context); | ||||
@@ -68,13 +70,13 @@ public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
templateEngine.setTemplateResolver(templateResolver); | templateEngine.setTemplateResolver(templateResolver); | ||||
Context context = new Context(); | |||||
context.setVariable("project", "Spring Boot Demo"); | |||||
context.setVariable("author", "Yangkai.Shen"); | |||||
context.setVariable("url", "https://github.com/xkcoding/spring-boot-demo"); | |||||
Context varContext = new Context(); | |||||
varContext.setVariable("project", "Spring Boot Demo"); | |||||
varContext.setVariable("author", "Yangkai.Shen"); | |||||
varContext.setVariable("url", "https://github.com/xkcoding/spring-boot-demo"); | |||||
String emailTemplate = templateEngine.process("test", context); | |||||
mailService.sendHtmlMail("237497819@qq.com", "这是一封模板HTML邮件", emailTemplate); | |||||
String emailTemplate = templateEngine.process("test", varContext); | |||||
mailService.sendHtmlMail("237497819@qq.com", "这是一封模板HTML邮件(自定义目录)", emailTemplate); | |||||
} | } | ||||
/** | /** | ||||
@@ -83,7 +85,7 @@ public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
* @throws MessagingException 邮件异常 | * @throws MessagingException 邮件异常 | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void sendAttachmentsMail() throws MessagingException { | |||||
void sendAttachmentsMail() throws MessagingException { | |||||
URL resource = ResourceUtil.getResource("static/xkcoding.png"); | URL resource = ResourceUtil.getResource("static/xkcoding.png"); | ||||
mailService.sendAttachmentsMail("237497819@qq.com", "这是一封带附件的邮件", "邮件中有附件,请注意查收!", resource.getPath()); | mailService.sendAttachmentsMail("237497819@qq.com", "这是一封带附件的邮件", "邮件中有附件,请注意查收!", resource.getPath()); | ||||
} | } | ||||
@@ -94,7 +96,7 @@ public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
* @throws MessagingException 邮件异常 | * @throws MessagingException 邮件异常 | ||||
*/ | */ | ||||
@Test | @Test | ||||
public void sendResourceMail() throws MessagingException { | |||||
void sendResourceMail() throws MessagingException { | |||||
String rscId = "xkcoding"; | String rscId = "xkcoding"; | ||||
String content = "<html><body>这是带静态资源的邮件<br/><img src=\'cid:" + rscId + "\' ></body></html>"; | String content = "<html><body>这是带静态资源的邮件<br/><img src=\'cid:" + rscId + "\' ></body></html>"; | ||||
URL resource = ResourceUtil.getResource("static/xkcoding.png"); | URL resource = ResourceUtil.getResource("static/xkcoding.png"); |
@@ -23,6 +23,7 @@ | |||||
<module>demo-base-properties</module> | <module>demo-base-properties</module> | ||||
<module>demo-base-async</module> | <module>demo-base-async</module> | ||||
<module>demo-base-exception</module> | <module>demo-base-exception</module> | ||||
<module>demo-base-email</module> | |||||
</modules> | </modules> | ||||
</project> | </project> |
@@ -1,25 +0,0 @@ | |||||
/target/ | |||||
!.mvn/wrapper/maven-wrapper.jar | |||||
### STS ### | |||||
.apt_generated | |||||
.classpath | |||||
.factorypath | |||||
.project | |||||
.settings | |||||
.springBeans | |||||
.sts4-cache | |||||
### IntelliJ IDEA ### | |||||
.idea | |||||
*.iws | |||||
*.iml | |||||
*.ipr | |||||
### NetBeans ### | |||||
/nbproject/private/ | |||||
/build/ | |||||
/nbbuild/ | |||||
/dist/ | |||||
/nbdist/ | |||||
/.nb-gradle/ |
@@ -1,441 +0,0 @@ | |||||
# spring-boot-demo-email | |||||
> 此 demo 主要演示了 Spring Boot 如何整合邮件功能,包括发送简单文本邮件、HTML邮件(包括模板HTML邮件)、附件邮件、静态资源邮件。 | |||||
## pom.xml | |||||
```xml | |||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<artifactId>spring-boot-demo-email</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
<packaging>jar</packaging> | |||||
<name>spring-boot-demo-email</name> | |||||
<description>Demo project for Spring Boot</description> | |||||
<parent> | |||||
<groupId>com.xkcoding</groupId> | |||||
<artifactId>spring-boot-demo</artifactId> | |||||
<version>1.0.0-SNAPSHOT</version> | |||||
</parent> | |||||
<properties> | |||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
<java.version>1.8</java.version> | |||||
<jasypt.version>2.1.1</jasypt.version> | |||||
</properties> | |||||
<dependencies> | |||||
<!-- Spring Boot 邮件依赖 --> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-mail</artifactId> | |||||
</dependency> | |||||
<!--jasypt配置文件加解密--> | |||||
<dependency> | |||||
<groupId>com.github.ulisesbocchio</groupId> | |||||
<artifactId>jasypt-spring-boot-starter</artifactId> | |||||
<version>${jasypt.version}</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-test</artifactId> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>cn.hutool</groupId> | |||||
<artifactId>hutool-all</artifactId> | |||||
</dependency> | |||||
<!-- Spring Boot 模板依赖 --> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>spring-boot-demo-email</finalName> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> | |||||
``` | |||||
## application.yml | |||||
```yaml | |||||
spring: | |||||
mail: | |||||
host: smtp.mxhichina.com | |||||
port: 465 | |||||
username: spring-boot-demo@xkcoding.com | |||||
# 使用 jasypt 加密密码,使用com.xkcoding.email.PasswordTest.testGeneratePassword 生成加密密码,替换 ENC(加密密码) | |||||
password: ENC(OT0qGOpXrr1Iog1W+fjOiIDCJdBjHyhy) | |||||
protocol: smtp | |||||
test-connection: true | |||||
default-encoding: UTF-8 | |||||
properties: | |||||
mail.smtp.auth: true | |||||
mail.smtp.starttls.enable: true | |||||
mail.smtp.starttls.required: true | |||||
mail.smtp.ssl.enable: true | |||||
mail.display.sendmail: spring-boot-demo | |||||
# 为 jasypt 配置解密秘钥 | |||||
jasypt: | |||||
encryptor: | |||||
password: spring-boot-demo | |||||
``` | |||||
## MailService.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* 邮件接口 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-21 11:16 | |||||
*/ | |||||
public interface MailService { | |||||
/** | |||||
* 发送文本邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
*/ | |||||
void sendSimpleMail(String to, String subject, String content, String... cc); | |||||
/** | |||||
* 发送HTML邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException; | |||||
/** | |||||
* 发送带附件的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param filePath 附件地址 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) throws MessagingException; | |||||
/** | |||||
* 发送正文中有静态资源的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param rscPath 静态资源地址 | |||||
* @param rscId 静态资源id | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) throws MessagingException; | |||||
} | |||||
``` | |||||
## MailServiceImpl.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* 邮件接口 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-21 13:49 | |||||
*/ | |||||
@Service | |||||
public class MailServiceImpl implements MailService { | |||||
@Autowired | |||||
private JavaMailSender mailSender; | |||||
@Value("${spring.mail.username}") | |||||
private String from; | |||||
/** | |||||
* 发送文本邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
*/ | |||||
@Override | |||||
public void sendSimpleMail(String to, String subject, String content, String... cc) { | |||||
SimpleMailMessage message = new SimpleMailMessage(); | |||||
message.setFrom(from); | |||||
message.setTo(to); | |||||
message.setSubject(subject); | |||||
message.setText(content); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
message.setCc(cc); | |||||
} | |||||
mailSender.send(message); | |||||
} | |||||
/** | |||||
* 发送HTML邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
@Override | |||||
public void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException { | |||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | |||||
helper.setFrom(from); | |||||
helper.setTo(to); | |||||
helper.setSubject(subject); | |||||
helper.setText(content, true); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
helper.setCc(cc); | |||||
} | |||||
mailSender.send(message); | |||||
} | |||||
/** | |||||
* 发送带附件的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param filePath 附件地址 | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
@Override | |||||
public void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) throws MessagingException { | |||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | |||||
helper.setFrom(from); | |||||
helper.setTo(to); | |||||
helper.setSubject(subject); | |||||
helper.setText(content, true); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
helper.setCc(cc); | |||||
} | |||||
FileSystemResource file = new FileSystemResource(new File(filePath)); | |||||
String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); | |||||
helper.addAttachment(fileName, file); | |||||
mailSender.send(message); | |||||
} | |||||
/** | |||||
* 发送正文中有静态资源的邮件 | |||||
* | |||||
* @param to 收件人地址 | |||||
* @param subject 邮件主题 | |||||
* @param content 邮件内容 | |||||
* @param rscPath 静态资源地址 | |||||
* @param rscId 静态资源id | |||||
* @param cc 抄送地址 | |||||
* @throws MessagingException 邮件发送异常 | |||||
*/ | |||||
@Override | |||||
public void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) throws MessagingException { | |||||
MimeMessage message = mailSender.createMimeMessage(); | |||||
MimeMessageHelper helper = new MimeMessageHelper(message, true); | |||||
helper.setFrom(from); | |||||
helper.setTo(to); | |||||
helper.setSubject(subject); | |||||
helper.setText(content, true); | |||||
if (ArrayUtil.isNotEmpty(cc)) { | |||||
helper.setCc(cc); | |||||
} | |||||
FileSystemResource res = new FileSystemResource(new File(rscPath)); | |||||
helper.addInline(rscId, res); | |||||
mailSender.send(message); | |||||
} | |||||
} | |||||
``` | |||||
## MailServiceTest.java | |||||
```java | |||||
/** | |||||
* <p> | |||||
* 邮件测试 | |||||
* </p> | |||||
* | |||||
* @author yangkai.shen | |||||
* @date Created in 2018-11-21 13:49 | |||||
*/ | |||||
public class MailServiceTest extends SpringBootDemoEmailApplicationTests { | |||||
@Autowired | |||||
private MailService mailService; | |||||
@Autowired | |||||
private TemplateEngine templateEngine; | |||||
@Autowired | |||||
private ApplicationContext context; | |||||
/** | |||||
* 测试简单邮件 | |||||
*/ | |||||
@Test | |||||
public void sendSimpleMail() { | |||||
mailService.sendSimpleMail("237497819@qq.com", "这是一封简单邮件", "这是一封普通的SpringBoot测试邮件"); | |||||
} | |||||
/** | |||||
* 测试HTML邮件 | |||||
* | |||||
* @throws MessagingException 邮件异常 | |||||
*/ | |||||
@Test | |||||
public void sendHtmlMail() throws MessagingException { | |||||
Context context = new Context(); | |||||
context.setVariable("project", "Spring Boot Demo"); | |||||
context.setVariable("author", "Yangkai.Shen"); | |||||
context.setVariable("url", "https://github.com/xkcoding/spring-boot-demo"); | |||||
String emailTemplate = templateEngine.process("welcome", context); | |||||
mailService.sendHtmlMail("237497819@qq.com", "这是一封模板HTML邮件", emailTemplate); | |||||
} | |||||
/** | |||||
* 测试HTML邮件,自定义模板目录 | |||||
* | |||||
* @throws MessagingException 邮件异常 | |||||
*/ | |||||
@Test | |||||
public void sendHtmlMail2() throws MessagingException { | |||||
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); | |||||
templateResolver.setApplicationContext(context); | |||||
templateResolver.setCacheable(false); | |||||
templateResolver.setPrefix("classpath:/email/"); | |||||
templateResolver.setSuffix(".html"); | |||||
templateEngine.setTemplateResolver(templateResolver); | |||||
Context context = new Context(); | |||||
context.setVariable("project", "Spring Boot Demo"); | |||||
context.setVariable("author", "Yangkai.Shen"); | |||||
context.setVariable("url", "https://github.com/xkcoding/spring-boot-demo"); | |||||
String emailTemplate = templateEngine.process("test", context); | |||||
mailService.sendHtmlMail("237497819@qq.com", "这是一封模板HTML邮件", emailTemplate); | |||||
} | |||||
/** | |||||
* 测试附件邮件 | |||||
* | |||||
* @throws MessagingException 邮件异常 | |||||
*/ | |||||
@Test | |||||
public void sendAttachmentsMail() throws MessagingException { | |||||
URL resource = ResourceUtil.getResource("static/xkcoding.png"); | |||||
mailService.sendAttachmentsMail("237497819@qq.com", "这是一封带附件的邮件", "邮件中有附件,请注意查收!", resource.getPath()); | |||||
} | |||||
/** | |||||
* 测试静态资源邮件 | |||||
* | |||||
* @throws MessagingException 邮件异常 | |||||
*/ | |||||
@Test | |||||
public void sendResourceMail() throws MessagingException { | |||||
String rscId = "xkcoding"; | |||||
String content = "<html><body>这是带静态资源的邮件<br/><img src=\'cid:" + rscId + "\' ></body></html>"; | |||||
URL resource = ResourceUtil.getResource("static/xkcoding.png"); | |||||
mailService.sendResourceMail("237497819@qq.com", "这是一封带静态资源的邮件", content, resource.getPath(), rscId); | |||||
} | |||||
} | |||||
``` | |||||
## welcome.html | |||||
> 此文件为邮件模板,位于 resources/templates 目录下 | |||||
```html | |||||
<!DOCTYPE html> | |||||
<html lang="en" xmlns:th="http://www.thymeleaf.org"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<title>SpringBootDemo(入门SpringBoot的首选Demo)</title> | |||||
<style> | |||||
body { | |||||
text-align: center; | |||||
margin-left: auto; | |||||
margin-right: auto; | |||||
} | |||||
#welcome { | |||||
text-align: center; | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div id="welcome"> | |||||
<h3>欢迎使用 <span th:text="${project}"></span> - Powered By <span th:text=" ${author}"></span></h3> | |||||
<span th:text="${url}"></span> | |||||
<div style="text-align: center; padding: 10px"> | |||||
<a style="text-decoration: none;" href="#" th:href="@{${url}}" target="_bank"> | |||||
<strong>spring-boot-demo,入门Spring Boot的首选Demo!:)</strong> | |||||
</a> | |||||
</div> | |||||
<div style="text-align: center; padding: 4px"> | |||||
如果对你有帮助,请任意打赏 | |||||
</div> | |||||
<div style="width: 100%;height: 100%;text-align: center;display: flex"> | |||||
<div style="flex: 1;"></div> | |||||
<div style="display: flex;width: 400px;"> | |||||
<div style="flex: 1;text-align: center;"> | |||||
<div> | |||||
<img width="180px" height="180px" src="http://xkcoding.com/resources/wechat-reward-image.png"> | |||||
</div> | |||||
<div>微信打赏</div> | |||||
</div> | |||||
<div style="flex: 1;text-align: center;"> | |||||
<div><img width="180px" height="180px" src="http://xkcoding.com/resources/alipay-reward-image.png"> | |||||
</div> | |||||
<div>支付宝打赏</div> | |||||
</div> | |||||
</div> | |||||
<div style="flex: 1;"></div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> | |||||
``` | |||||
## 参考 | |||||
- Spring Boot 官方文档:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-email | |||||
- Spring Boot 官方文档:https://docs.spring.io/spring/docs/5.1.2.RELEASE/spring-framework-reference/integration.html#mail |
@@ -1,16 +0,0 @@ | |||||
package com.xkcoding.email; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringRunner; | |||||
@RunWith(SpringRunner.class) | |||||
@SpringBootTest | |||||
public class SpringBootDemoEmailApplicationTests { | |||||
@Test | |||||
public void contextLoads() { | |||||
} | |||||
} |
@@ -43,7 +43,6 @@ | |||||
<!-- <module>demo-upload</module>--> | <!-- <module>demo-upload</module>--> | ||||
<!-- <module>demo-cache-redis</module>--> | <!-- <module>demo-cache-redis</module>--> | ||||
<!-- <module>demo-cache-ehcache</module>--> | <!-- <module>demo-cache-ehcache</module>--> | ||||
<!-- <module>demo-email</module>--> | |||||
<!-- <module>demo-task</module>--> | <!-- <module>demo-task</module>--> | ||||
<!-- <module>demo-task-quartz</module>--> | <!-- <module>demo-task-quartz</module>--> | ||||
<!-- <module>demo-task-xxl-job</module>--> | <!-- <module>demo-task-xxl-job</module>--> | ||||