後端程式常常需要寄信給使用者,如註冊完成、忘記密碼、訂購完成等等。本文章將介紹如何利用 FreeMarker 建立信件模板,並利用 Spring Mail 透過 Gmail SMTP 傳送 email。
Table of Contents
FreeMarker
FreeMarker 是一個 template engine,可以用來建立 email 內容的模板。首先,我們要引入以下的依賴。
dependencies { implementation("org.springframework.boot:spring-boot-starter-freemarker") }
在 application.properties 中,加入以下的設定。spring.freemarker.template-loader-path
是用來設定模板檔案的位址。在以下的範例中,我們將它設定為在 src/resources/templates/ 下。
spring.freemarker.cache=true spring.freemarker.template-loader-path=classpath:/templates/
在 src/resources/templates/ 下新增模板檔案 EmailTemplate.ftlh,其內容如下。在模板檔案的內容中,有兩個變數,${logo}
和 ${content}
。之後,在程式中可以在變數的地方取代我們想要的資料。
<html> <body> <div> <img src="cid:${logo}" /> </div> <br/> <div>${content}</div> </body> </html>
Spring Mail
接下來,我們將利用 Spring Mail 來透過 STMP 傳送 email。首先,我們要引入以下的依賴。
dependencies { implementation("org.springframework.boot:spring-boot-starter-mail") }
在 application.properties 中,我們用 Gmail STMP 作為 SMTP server。
spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=<login username to smtp server> spring.mail.password=<login password to smtp server> spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true spring.mail.properties.mail.debug=true
現在所有的設定都完成了。接下來,我們將利用以下的程式碼來傳送 email。在程式碼中,我們是用 JavaMailSender 來傳送 email,可是我們並沒有引入 JavaMailSender 的依賴啊。這是因為 Spring Mail 是基於 JavaMailSender 來實現傳送 email 的功能。
首先,我們呼叫 JavaMailSender.createMimeMessage() 來建立一個 MimeMessage。然後,利用 MimeMessageHelper 來設定 email 的傳送者(from)、接收者(to)和主旨(subject)。
用 FreeMarker 載入模板檔案,並呼叫 FreeMarkerTemplateUtils.processTemplateIntoString() 將信件的 logo 和內容填入模板中。然呼叫 MimeMessageHelper.setText() 將模板內容傳入 MimeMessage。然後,呼叫 MimeMessageHelper.addInline() 將 logo 檔案加入到 MimeMessage 中。值得注意的是,addInline() 必須要在 setText() 之後呼叫,不然 logo 不會顯示出來。
最後,呼叫 JavaMailSender.send() 送出 email。
@Service class EmailService(private val javaMailSender: JavaMailSender, private val freemarkerConfig: Configuration) { fun sendEmail(to: String, subject: String, content: String) { val mimeMessage = javaMailSender.createMimeMessage() val helper = MimeMessageHelper(mimeMessage, true) helper.setFrom("Wayne's Talk <waynestalk@gmail.com>") helper.setTo(to) helper.setSubject(subject) val logoClassPathResource = ClassPathResource("static/logo.png") val logo = ByteArrayResource(logoClassPathResource.inputStream.readAllBytes()) val parameters = mapOf( "logo" to "logo.png", "content" to content, ) val template = freemarkerConfig.getTemplate("EmailTemplate.ftlh") val text = FreeMarkerTemplateUtils.processTemplateIntoString(template, parameters) helper.setText(text, true) // This line must be after helper.setText(), otherwise the logo won't be displayed helper.addInline("logo.png", logo, "image/png") javaMailSender.send(mimeMessage) } }
結語
Spring Mail 使用起來相當地簡單。主要的問題是如何產生出複雜的信件內容。而這部分可以用 FreeMarker 輕鬆地達成。這兩個套件搭配起來使用,可以輕易地產生出複雜的信件。