Menggunakan Template Email ThymeLeaf dan FreeMarker dengan Spring

1. Ikhtisar

Di artikel kami sebelumnya, kami melihat cara menggunakan Spring untuk menulis dan mengirim email teks.

Tetapi juga memungkinkan untuk menggunakan mesin template Spring untuk menulis email HTML yang indah dengan konten dinamis .

Dalam tutorial ini, kita akan belajar bagaimana melakukannya menggunakan yang paling terkenal di antaranya: Thymeleaf dan FreeMarker .

2. Buka Email HTML

Mari kita mulai dari tutorial Spring Email.

Pertama, kami akan menambahkan metode ke kelas EmailServiceImpl untuk mengirim email dengan badan HTML:

private void sendHtmlMessage(String to, String subject, String htmlBody) throws MessagingException { MimeMessage message = emailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); helper.setTo(to); helper.setSubject(subject); helper.setText(htmlBody, true); emailSender.send(message); }

Kami menggunakan MimeMessageHelper untuk mengisi pesan . Bagian penting adalah nilai sebenarnya yang diteruskan ke metode setText : ini menentukan tipe konten HTML.

Mari kita lihat sekarang bagaimana membangun htmlBody ini menggunakan template Thymeleaf dan FreeMarker.

3. Konfigurasi Thymeleaf

Mari kita mulai dengan konfigurasi. Kita bisa mengisolasi ini di kelas yang disebut EmailConfiguration .

Pertama, kita harus menyediakan pemecah template untuk menemukan direktori file template .

3.1. Template sebagai Sumber Daya Classpath

File template dapat dikirimkan dalam file JAR , yang merupakan cara termudah untuk menjaga kohesi antara template dan data inputnya.

Untuk menemukan template dari JAR, kami menggunakan ClassLoaderTemplateResolver . Template kami ada di direktori main / resources / mail-templates , jadi kami menyetel atribut Prefix sesuai dengan direktori resource :

@Bean public ITemplateResolver thymeleafTemplateResolver() { ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setPrefix("mail-templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode("HTML"); templateResolver.setCharacterEncoding("UTF-8"); return templateResolver; }

3.2. Template Dari Direktori Eksternal

Dalam kasus lain, kami mungkin ingin mengubah template tanpa harus membangun kembali dan menerapkan . Untuk mencapai ini, kita dapat meletakkan template pada sistem file sebagai gantinya.

Mungkin berguna untuk mengonfigurasi jalur ini di application.properties sehingga kami dapat memodifikasinya untuk setiap penerapan. Properti ini dapat diakses menggunakan anotasi @Value :

@Value("${spring.mail.templates.path}") private String mailTemplatesPath;

Kami kemudian meneruskan nilai ini ke FileTemplateResolver , sebagai ganti ClassLoaderTemplateResolver dalam metode thymeleafTemplateResolver kami :

FileTemplateResolver templateResolver = new FileTemplateResolver(); templateResolver.setPrefix(mailTemplatesPath);

3.3. Konfigurasi Mesin Thymeleaf

Langkah terakhir adalah membuat metode pabrik untuk mesin Thymeleaf. Kita harus memberi tahu mesin TemplateResolver mana yang telah kita pilih, yang dapat kita masukkan melalui parameter ke metode pabrik kacang:

@Bean public SpringTemplateEngine thymeleafTemplateEngine(ITemplateResolver templateResolver) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); templateEngine.setTemplateEngineMessageSource(emailMessageSource()); return templateEngine; }

Di sini, resolver yang kita buat sebelumnya disuntikkan secara otomatis oleh Spring ke dalam metode pabrik mesin template.

4. Konfigurasi FreeMarker

Dalam cara yang sama seperti Thymeleaf, di EmailConfiguration kelas, kami akan mengkonfigurasi resolver template untuk FreeMarker template (.ftl ) :

Dan kali ini, lokasi template akan dikonfigurasi di kacang FreeMarkerConfigurer .

4.1. Template di Classpath

Di sini, kami memiliki opsi yang sama seperti Thymeleaf. Mari kita konfigurasikan template sebagai resource classpath:

@Bean public FreeMarkerConfigurer freemarkerClassLoaderConfig() { Configuration configuration = new Configuration(Configuration.VERSION_2_3_27); TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), "/mail-templates"); configuration.setTemplateLoader(templateLoader); FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); freeMarkerConfigurer.setConfiguration(configuration); return freeMarkerConfigurer; }

4.2. Template di Sistem File

Untuk mengonfigurasi template dari jalur lain di sistem file, kita perlu mengganti contoh TemplateLoader :

TemplateLoader templateLoader = new FileTemplateLoader(new File(mailTemplatesPath));

5. Lokalisasi dengan Thymeleaf dan FreeMarker

Untuk mengelola terjemahan dengan Thymeleaf, kita dapat menentukan instance MessageSource ke mesin :

@Bean public ResourceBundleMessageSource emailMessageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("mailMessages"); return messageSource; }
@Bean public SpringTemplateEngine thymeleafTemplateEngine() { ... templateEngine.setTemplateEngineMessageSource(emailMessageSource()); ... }

Kemudian, kami akan membuat bundel sumber daya untuk setiap lokal yang kami dukung:

src/main/resources/mailMessages_xx_YY.properties

Karena FreeMarker mengusulkan pelokalan dengan menduplikasi templat , kami tidak perlu mengonfigurasi sumber pesan di sana.

6. Isi Template Thymeleaf

Selanjutnya, mari kita lihat file template-thymeleaf.html :

Seperti yang bisa dilihat, kita telah menggunakan notasi Thymeleaf, yaitu $ {…} untuk variabel dan # {…} untuk string yang dilokalkan .

Karena mesin templat dikonfigurasi dengan benar, sangat mudah untuk menggunakannya: Kami hanya akan membuat objek Konteks yang berisi variabel templat (diteruskan sebagai Peta di sini).

Kemudian, kami akan meneruskannya ke metode proses bersama dengan nama template:

@Autowired private SpringTemplateEngine thymeleafTemplateEngine; @Override public void sendMessageUsingThymeleafTemplate( String to, String subject, Map templateModel) throws MessagingException { Context thymeleafContext = new Context(); thymeleafContext.setVariables(templateModel); String htmlBody = thymeleafTemplateEngine.process("template-thymeleaf.html", thymeleafContext); sendHtmlMessage(to, subject, htmlBody); }

Sekarang, mari kita lihat bagaimana melakukan hal yang sama dengan FreeMarker.

7. Konten Template FreeMarker

Seperti yang dapat dilihat, sintaks FreeMarker lebih sederhana, tetapi sekali lagi tidak mengelola string yang dilokalkan. Jadi, inilah versi bahasa Inggrisnya:

Hi ${recipientName}

${text}

Regards,

${senderName} at Baeldung

Kemudian, kita harus menggunakan kelas FreeMarkerConfigurer untuk mendapatkan file template, dan terakhir, FreeMarkerTemplateUtils untuk memasukkan data dari Peta kita :

@Autowired private FreeMarkerConfigurer freemarkerConfigurer; @Override public void sendMessageUsingFreemarkerTemplate( String to, String subject, Map templateModel) throws IOException, TemplateException, MessagingException { Template freemarkerTemplate = freemarkerConfigurer.getConfiguration() .getTemplate("template-freemarker.ftl"); String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerTemplate, templateModel); sendHtmlMessage(to, subject, htmlBody); }

Untuk melangkah lebih jauh, kita akan melihat bagaimana menambahkan logo ke tanda tangan email kita.

8. Email Dengan Gambar Tertanam

Karena sangat umum untuk menyertakan gambar dalam email HTML, kita akan melihat bagaimana melakukannya menggunakan lampiran CID.

The first change concerns the sendHtmlMessage method. We have to set MimeMessageHelper as multi-part by passing true to the second argument of the constructor:

MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

Then, we have to get the image file as a resource. We can use the @Value annotation for this:

@Value("classpath:/mail-logo.png") Resource resourceFile;

Notice that the mail-logo.png file is in the src/main/resources directory.

Back to the sendHtmlMessage method, we'll add resourceFile as an inline attachment, to be able to reference it with CID:

helper.addInline("attachment.png", resourceFile);

Finally, the image has to be referenced from both Thymeleaf and FreeMarker emails using CID notation:

9. Kesimpulan

Di artikel ini, kami telah melihat cara mengirim email Thymeleaf dan FreeMarker, termasuk konten HTML yang kaya.

Untuk menyimpulkan, sebagian besar pekerjaan terkait dengan Spring; Oleh karena itu, penggunaan satu atau lainnya sangat mirip untuk kebutuhan sederhana seperti mengirim email .

Seperti biasa, kode sumber lengkap dari contoh dapat ditemukan di GitHub.