SpringBoot入門 (十) 傳送郵件
本文記錄學習在SpringBoot中傳送郵件。
一 郵件傳送過程
傳送郵件是一個我們在專案中經常會用到的功能,如在使用者註冊時傳送驗證碼,賬戶啟用等都會用到。完整的一個郵件傳送過程主要包含以下幾個步驟:
1 發件人在使用者郵件代理上寫郵件內容及收件人的郵箱地址;
2 使用者郵件代理根據發件人填寫的郵件資訊,生成一封符合郵件格式的郵件;
3 使用者郵件代理把郵件傳送到發信人的郵件伺服器上;
4 發件人的郵件伺服器使用 SMTP 協議把這封郵件傳送到收件人的郵件伺服器上;
5 收件人的郵件伺服器收到郵件後,把這封郵件放到收件人在這個伺服器上的信箱中;
6 收件人使用使用者郵件代理來收取郵件。
二 傳送郵件示例
以前傳送郵件時,呼叫 JavaMail 的相關 API 來開發實現,需要我們自己去組裝訊息體,程式碼量比較大,實現起來也不是很容易;Spring 提供的JavaMailSender 對JavaMail的Api做了一定的封裝,簡化了發郵件的過程。JavaMailSender 提供了強大的郵件傳送功能,可支援各種型別的郵件傳送。Spring Boot在JavaMailSender 的基礎上又做了進一步的封裝,讓我們的使用更加的簡單。
在pom.xml檔案中引入需要得依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
在application.properties中配置郵件服務相關資訊(測試使用得是QQ郵件服務)
# Email #郵件預設字符集 spring.mail.default-encoding=UTF-8 #郵件服務地址 spring.mail.host=smtp.qq.com #郵件服務協議,可以不寫(檢視原始碼可知,沒有時預設值是smtp ) #spring.mail.protocol=smtp #埠 spring.mail.port=25 #賬號 spring.mail.username=********@qq.com #密碼 使用第三方傳送郵件時,需要開通授權,所以此處要寫郵箱授權碼 spring.mail.password=****************
完成了上邊得配置後,在啟動服務得時候,SpringBoot會根據我們得配置,為我們初始化好一個JavaMailSender類供我們呼叫,我們只需要在要使用得地方注入就可以了。
定義一個郵件服務介面,提供我們得郵件服務方法,其他業務中用到發郵件功能時,呼叫找個介面就可以了
public interface EmailSenderService { /** * 傳送文字訊息 * @param subject 郵件主題 * @param content 郵件內容 * @param to 收件人(可變引數,多個時用逗號隔開) */ void sendTextMail(String subject, String content, String... to); }
@Service public class EmailSenderServiceImpl implements EmailSenderService { @Autowired private JavaMailSender javaMailSender; //發件人郵箱 @Value("${spring.mail.username}") private String from; @Override public void sendTextMail(String subject, String content, String... to) { SimpleMailMessage mailMessage = new SimpleMailMessage(); mailMessage.setFrom(from); mailMessage.setTo(to); mailMessage.setSubject(subject); mailMessage.setText(content); mailMessage.setSentDate(new Date()); javaMailSender.send(mailMessage); } }
如上,我們在實現類中注入JavaMailSender後直接呼叫它send方法就可以完成發郵件。其他業務中用到發郵件業務了,直接呼叫EmailSenderService 介面得方法即可。我們完全也可以把JavaMailSender直接注入到我們得各個業務模組中去,在發郵件時直接呼叫JavaMailSender得send方法發郵件。但是還是推薦將郵件傳送相關功能獨立起來,便於維護。
上邊我們實現了傳送一個文字郵件,有時候我們還需要在傳送郵件時附帶傳送附件,這種也是支援的,我們新增介面及實現方法
/** * 傳送帶附件郵件 * @param subject 主題 * @param content 內容 * @param filePath 附件得本地路徑 * @param fileName 附件名 * @param to 收件人 */ void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to);
@Override public void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to) { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); try { MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content); //附件 FileSystemResource file = new FileSystemResource(new File(filePath)); helper.addAttachment(fileName, file); javaMailSender.send(mimeMessage); } catch (MessagingException e) { e.printStackTrace(); } }
如果我們傳送郵件時,除了收件人之外,還想讓某些人知道即抄送某些人,這種也是支援得,介面及實現方法如下:
/** * 傳送一個郵件並抄送 * @param subject 主題 * @param content 內容 * @param ccList 抄送人(可以有多個) * @param to 收件人(可以有多個) */ void sendTextMail(String subject, String content, List<String> ccList, String... to);
@Override public void sendTextMail(String subject, String content, List<String> ccList, String... to) { //收件人地址 InternetAddress[] addressesTo = new InternetAddress[to.length]; if(to != null && to.length>0){ for(int i=0;i<to.length;i++){ InternetAddress addressTo = null; try { addressTo = new InternetAddress(to[i]); addressesTo[i] = addressTo; } catch (AddressException e) { e.printStackTrace(); } } } //抄送人地址 InternetAddress[] addressesCc = new InternetAddress[ccList.size()]; if(ccList != null && ccList.size() > 0){ for(int i=0;i<ccList.size();i++){ String ccAdd = ccList.get(i); InternetAddress address = null; try { address = new InternetAddress(ccAdd); addressesCc[i] = address; } catch (AddressException e) { e.printStackTrace(); } } } MimeMessagePreparator preparator = new MimeMessagePreparator() { @Override public void prepare(MimeMessage mimeMessage) throws Exception { mimeMessage.setFrom(from); mimeMessage.setSubject(subject); mimeMessage.setText(content); mimeMessage.setRecipients(Message.RecipientType.TO, addressesTo); mimeMessage.setRecipients(Message.RecipientType.CC, addressesCc); } }; javaMailSender.send(preparator); }
如上方法就實現了向多人傳送郵件並且抄送多人