Spring Boot demo系列(七):郵件服務
阿新 • • 發佈:2020-09-19
1 概述
Spring Boot
整合郵件服務,包括髮送普通的文字郵件以及帶附件的郵件。
2 郵箱選擇
這裡選擇的是QQ
郵箱作為傳送的郵箱,當然也可以選擇其他的郵箱,只是具體的配置不一樣。
使用QQ
郵箱的話,需要在個人設定中開啟SMTP
服務:
傳送簡訊後完成驗證即可,會有一個授權碼,先複製下來儲存。
3 具體實現
3.1 依賴
提供了starter
:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
gradle
:
implementation 'org.springframework.boot:spring-boot-starter-mail'
3.2 郵件介面
只有兩個簡單的介面,一個是傳送純文字的,一個是傳送帶附件的:
public interface MailService { void sendSimpleMail(String to,String subject,String content); void sendAttachmentMail(String to, String subject, String content, Path file) throws MessagingException; }
3.3 介面實現
@Service @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class MailServiceImpl implements MailService{ private final JavaMailSender sender; @Value("${spring.mail.username}") private String from; @Override public void sendSimpleMail(String to, String subject, String content) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(to); message.setSubject(subject); message.setText(content); sender.send(message); } @Override public void sendAttachmentMail(String to, String subject, String content, Path file) throws MessagingException { MimeMessage message = sender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message,true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content); helper.addAttachment(file.getFileName().toString(),new FileSystemResource(file)); sender.send(message); } }
JavaMailSender
是Spring Boot
攜帶的郵件傳送介面,注入後可以傳送SimpleMailMessage
以及MimeMessage
型別的資訊。
SimpleMailMessage
:簡單的郵件資訊物件,封裝了一些常見的屬性,比如寄信地址以及收信地址,傳送日期,主題,內容等MimeMessage
:傳送MIME
型別的郵件資訊,MIME
指的是Multipurpose Internet Mail Extensiosns
,是描述訊息內容型別的因特網標準,能包含文字,影象,音訊,視訊以及其他應用程式專用的資料MimeMessageHelper
:用於設定MimeMessage
屬性的類,可以利用其中的addAttachment
新增附件setFrom
/setTo
/setSubject
/setText
:分別表示設定寄信地址
/收信地址
/主題
/內容
3.4 測試類
@SpringBootTest
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
class DemoApplicationTests {
private final MailService service;
@Test
void contextLoads() throws URISyntaxException, MessagingException {
service.sendSimpleMail("[email protected]","這是主題","這是內容");
service.sendAttachmentMail("[email protected]","這是主題","這是內容", Path.of(Objects.requireNonNull(getClass().getClassLoader().getResource("pic/1.jpg")).toURI()));
//附件為resources下pic/1.jpg
service.sendAttachmentMail("[email protected]","這是主題","這是內容", Path.of("/","srv","http","1.jpg"));
//附件為/srv/http/1.jpg
}
傳送文字直接指定主題和內容即可,傳送帶附件的話:
- 如果是
resources
下的內容,使用getClass().getClassLoader().getReource("xxx/xxx")
- 如果是絕對路徑,使用
Path.of("/","path1","path2",...,"filename")
3.5 配置檔案
spring:
mail:
host: smtp.qq.com
username: [email protected]
password: xxxxxxxxxx
port: 465
properties:
mail:
smtp:
ssl:
enable: true
auth: true
starttls:
enable: true
required: true
作為Demo
使用只需要修改username
以及password
即可。
username
:傳送的使用者郵箱password
:不是郵箱密碼,而是授權碼,就是剛才開啟SMTP
服務出現的授權碼
其他配置說明:
host
:SMTP
伺服器地址port
:埠,可以選擇465
/587
,host
以及port
可以參考QQ
郵箱文件properties
:裡面都是一些安全設定,開啟SSL
以及認證等
3.6 測試
修改測試類的郵箱,執行單元測試即可。
如果沒通過,可以參考這裡,羅列了常見的錯誤碼以及可能的解決方案。
4 加密
由於使用者名稱以及密碼都直接寫在了配置檔案中,如果洩露的話會很危險,因此需要對配置檔案進行加密。
具體的話可以參考筆者之前的原力計劃文章,戳這裡。
4.1 依賴
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
gradle
:
implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3")
4.2 配置檔案
配置檔案只需要加上加密口令即可:
jasypt:
encryptor:
password: test
預設使用的是PBE
加密演算法,PBE
其實是一種組合加密演算法,預設是採用HCMA
演算法(混合CMA-ES
演算法)+SHA512
訊息摘要演算法+AES256
對稱加密演算法。
另外,如果不想在配置檔案直接寫上加密的口令,可以使用以下三種方法對口令進行引數化:
命令列引數(執行時設定):
java -jar xxx.jar --jasypt.encryptor.password=test
應用環境變數(執行時設定):
java -Djasypt.encryptor.password=test -jar xxx.jar
系統環境變數(在配置檔案中設定):
jasypt:
encryptor:
password: ${TEST}
# 表示獲取環境變數TEST的值作為加密口令
4.3 測試類
新建一個測試類:
@SpringBootTest
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class EncryptAndDecrypt {
private final StringEncryptor encryptor;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
@Test
public void encrypt()
{
System.out.println(encryptor.encrypt(username));
System.out.println(encryptor.encrypt(password));
}
@Test
public void decrypt()
{
System.out.println(username);
System.out.println(password);
}
}
4.4 獲取密文
假設明文如下:
執行encrypt
即可,輸出如下:
4.5 替換明文
加上字首ENC(
以及字尾)
去替換明文:
4.6 測試
獲取明文直接執行decrypt
即可,輸出:
這樣就完成加密了。
5 原始碼
Java
版:
Kotlin
版: