【Spring Boot】(31)、使用SpringBoot傳送mail郵件
1、前言
傳送郵件應該是網站的必備拓展功能之一,註冊驗證,忘記密碼或者是給使用者傳送營銷資訊。正常我們會用JavaMail相關api來寫傳送郵件的相關程式碼,但現在springboot提供了一套更簡易使用的封裝。
2、Mail依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>${spring-boot-mail.version}</version> </dependency>
來看看其依賴樹:
可以看到spring-boot-starter-mail-xxx.jar對Sun公司的郵件api功能進行了相應的封裝。
3、Mail自動配置類: MailSenderAutoConfiguration
其實肯定可以猜到Spring Boot對Mail功能已經配置了相關的基本配置資訊,它是Spring Boot官方提供,其類為MailSenderAutoConfiguration:
//MailSenderAutoConfiguration @Configuration @ConditionalOnClass({ MimeMessage.class, MimeType.class }) @ConditionalOnMissingBean(MailSender.class) @Conditional(MailSenderCondition.class) @EnableConfigurationProperties(MailProperties.class) @Import(JndiSessionConfiguration.class) public class MailSenderAutoConfiguration { private final MailProperties properties; private final Session session; public MailSenderAutoConfiguration(MailProperties properties, ObjectProvider<Session> session) { this.properties = properties; this.session = session.getIfAvailable(); } @Bean public JavaMailSenderImpl mailSender() { JavaMailSenderImpl sender = new JavaMailSenderImpl(); if (this.session != null) { sender.setSession(this.session); } else { applyProperties(sender); } return sender; } //other code... }
首先,它會通過注入Mail的屬性配置類MailProperties:
@ConfigurationProperties(prefix = "spring.mail") public class MailProperties { private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); /** * SMTP server host. */ private String host; /** * SMTP server port. */ private Integer port; /** * Login user of the SMTP server. */ private String username; /** * Login password of the SMTP server. */ private String password; /** * Protocol used by the SMTP server. */ private String protocol = "smtp"; /** * Default MimeMessage encoding. */ private Charset defaultEncoding = DEFAULT_CHARSET; /** * Additional JavaMail session properties. */ private Map<String, String> properties = new HashMap<String, String>(); /** * Session JNDI name. When set, takes precedence to others mail settings. */ private String jndiName; /** * Test that the mail server is available on startup. */ private boolean testConnection; //other code... }
在MailSenderAutoConfiguration自動配置類中,建立了一個Bean,其類為JavaMailSenderImpl,它是Spring專門用來發送Mail郵件的服務類,SpringBoot也使用它來發送郵件。它是JavaMailSender介面的實現類,通過它的send()方法來發送不同型別的郵件,主要分為兩類,一類是簡單的文字郵件,不帶任何html格式,不帶附件,不帶圖片等簡單郵件,還有一類則是帶有html格式文字或者連結,有附件或者圖片的複雜郵件。
4、傳送郵件
通用配置application.properties:
# 設定郵箱主機
spring.mail.host=smtp.qq.com
# 設定使用者名稱
[email protected]
# 設定密碼,該處的密碼是QQ郵箱開啟SMTP的授權碼而非QQ密碼
spring.mail.password=pwvtabrwxogxidac
# 設定是否需要認證,如果為true,那麼使用者名稱和密碼就必須的,
# 如果設定false,可以不設定使用者名稱和密碼,當然也得看你的對接的平臺是否支援無密碼進行訪問的。
spring.mail.properties.mail.smtp.auth=true
# STARTTLS[1] 是對純文字通訊協議的擴充套件。它提供一種方式將純文字連線升級為加密連線(TLS或SSL),而不是另外使用一個埠作加密通訊。
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
mail.from=${spring.mail.username}
[email protected]
由於使用QQ郵箱的使用者佔多數,所以這裡選擇QQ郵箱作為測試。還有注意的是spring.mail.password這個值不是QQ郵箱的密碼,而是QQ郵箱給第三方客戶端郵箱生成的授權碼。具體要登入QQ郵箱,點選設定,找到SMTP服務:
預設SMTP服務是關閉的,即預設狀態為關閉狀態,如果是第一次操作,點選開啟後,會通過驗證會獲取到授權碼;而我之前已經開啟過SMTP服務,所以直接點選生成授權碼後通過驗證獲取到授權碼。
自定義的MailProperties配置類,用於解析mail開頭的配置屬性:
@Component
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
private String from;
private String to;
//getter and setter...
}
4.1、測試傳送簡單文字郵件
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleMailTest {
@Autowired
private MailService mailService;
@Test
public void sendMail(){
mailService.sendSimpleMail("測試Springboot傳送郵件", "傳送郵件...");
}
}
sendSimpleMail():
@Override
public void sendSimpleMail(String subject, String text) {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom(mailProperties.getFrom());
mailMessage.setTo(mailProperties.getTo());
mailMessage.setSubject(subject);
mailMessage.setText(text);
javaMailSender.send(mailMessage);
}
觀察結果:
4.2、測試傳送帶有連結和附件的複雜郵件
事先準備一個檔案file.txt,放在resources/public/目錄下。
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class MimeMailTest {
@Autowired
private MailService mailService;
@Test
public void testMail() throws MessagingException {
Map<String, String> attachmentMap = new HashMap<>();
attachmentMap.put("附件", "file.txt的絕對路徑");
mailService.sendHtmlMail("測試Springboot傳送帶附件的郵件", "歡迎進入<a href=\"http://www.baidu.com\">百度首頁</a>", attachmentMap);
}
}
sendHtmlMail():
@Override
public void sendHtmlMail(String subject, String text, Map<String, String> attachmentMap) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//是否傳送的郵件是富文字(附件,圖片,html等)
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
messageHelper.setFrom(mailProperties.getFrom());
messageHelper.setTo(mailProperties.getTo());
messageHelper.setSubject(subject);
messageHelper.setText(text, true);//重點,預設為false,顯示原始html程式碼,無效果
if(attachmentMap != null){
attachmentMap.entrySet().stream().forEach(entrySet -> {
try {
File file = new File(entrySet.getValue());
if(file.exists()){
messageHelper.addAttachment(entrySet.getKey(), new FileSystemResource(file));
}
} catch (MessagingException e) {
e.printStackTrace();
}
});
}
javaMailSender.send(mimeMessage);
}
觀察結果:
4.3、測試傳送模版郵件
這裡使用Freemarker作為模版引擎。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>${spring-boot-freemarker.version}</version>
</dependency>
事先準備一個模版檔案mail.ftl
<html>
<body>
<h3>你好, <span style="color: red;">${username}</span>, 這是一封模板郵件!</h3>
</body>
</html>
模版測試類:
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class MailTemplateTest {
@Autowired
private MailService mailService;
@Test
public void testFreemarkerMail() throws MessagingException, IOException, TemplateException {
Map<String, Object> params = new HashMap<>();
params.put("username", "Cay");
mailService.sendTemplateMail("測試Springboot傳送模版郵件", params);
}
}
sendTemplateMail():
@Override
public void sendTemplateMail(String subject, Map<String, Object> params) throws MessagingException, IOException, TemplateException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(mailProperties.getFrom());
helper.setTo(mailProperties.getTo());
Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
configuration.setClassForTemplateLoading(this.getClass(), "/templates");
String html = FreeMarkerTemplateUtils.processTemplateIntoString(configuration.getTemplate("mail.ftl"), params);
helper.setSubject(subject);
helper.setText(html, true);//重點,預設為false,顯示原始html程式碼,無效果
javaMailSender.send(mimeMessage);
}
觀察結果:
====================打個廣告,歡迎關注====================
QQ: |
412425870 |
微信公眾號:Cay課堂 |
|
csdn部落格: |
http://blog.csdn.net/caychen |
碼雲: |
https://gitee.com/caychen/ |
github: |
https://github.com/caychen |
點選群號或者掃描二維碼即可加入QQ群:328243383(1群) |
|
點選群號或者掃描二維碼即可加入QQ群: |
|