Menggunakan Templat E-mel ThymeLeaf dan FreeMarker dengan Spring

1. Gambaran keseluruhan

Dalam artikel sebelumnya, kami melihat cara menggunakan Spring untuk menulis dan menghantar e-mel teks.

Tetapi mungkin juga menggunakan mesin templat Spring untuk menulis e-mel HTML yang indah dengan kandungan dinamik .

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

2. E-mel HTML Musim Semi

Mari kita mulakan dari tutorial Spring Email.

Pertama, kami akan menambahkan kaedah ke kelas EmailServiceImpl untuk menghantar e-mel 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 mesej . Bahagian penting adalah nilai sebenar yang diteruskan ke kaedah setText : ia menentukan jenis kandungan HTML.

Mari lihat sekarang bagaimana membina htmlBody ini menggunakan templat Thymeleaf dan FreeMarker.

3. Konfigurasi Thymeleaf

Mari mulakan dengan konfigurasi. Kita boleh mengasingkannya dalam kelas yang disebut EmailConfiguration .

Pertama, kita harus menyediakan pemecah templat untuk mencari direktori fail templat .

3.1. Templat sebagai Sumber Classpath

Fail templat dapat dikirimkan ke dalam file JAR , yang merupakan cara termudah untuk menjaga perpaduan antara templat dan data inputnya.

Untuk mencari templat dari JAR, kami menggunakan ClassLoaderTemplateResolver . Templat kami ada di direktori template utama / sumber / surat , jadi kami menetapkan atribut Awalan relatif ke direktori sumber :

@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. Templat Dari Direktori Luar

Dalam kes lain, kami mungkin ingin mengubah templat tanpa harus membangun kembali dan menyebarkan . Untuk mencapai ini, kita boleh meletakkan templat pada sistem fail sebagai gantinya.

Mungkin berguna untuk mengkonfigurasi jalur ini di application.properties sehingga kita dapat mengubahnya untuk setiap penerapan. Harta ini dapat diakses menggunakan penjelasan @Value :

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

Kami kemudian menyampaikan nilai ini ke FileTemplateResolver , sebagai ganti ClassLoaderTemplateResolver dalam kaedah thymeleafTemplateResolver kami :

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

3.3. Konfigurasikan Thymeleaf Engine

Langkah terakhir adalah membuat kaedah kilang untuk mesin Thymeleaf. Kita perlu memberitahu mesin mana TemplateResolver yang telah kita pilih, yang boleh kita suntik melalui parameter ke kaedah kilang kacang:

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

Di sini, penyelesai yang kami buat sebelumnya disuntik secara automatik oleh Spring ke dalam kaedah kilang mesin templat.

4. Konfigurasi FreeMarker

Dengan cara yang sama seperti Thymeleaf, di kelas Konfigurasi Email , kami akan mengkonfigurasi pemecah templat untuk templat FreeMarker (.ftl ) :

Dan kali ini, lokasi templat akan dikonfigurasi dalam kacang FreeMarkerConfigurer .

4.1. Templat di Pathpath

Di sini, kami mempunyai pilihan yang sama dengan Thymeleaf. Mari konfigurasikan templat sebagai sumber 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. Templat pada Sistem Fail

Untuk mengkonfigurasi templat dari jalan lain dalam sistem fail, kita perlu mengganti contoh TemplateLoader :

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

5. Penyetempatan dengan Thymeleaf dan FreeMarker

Bagi mengurus terjemahan dengan Thymeleaf, kita boleh menentukan MessageSource contoh kepada enjin :

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

Kemudian, kami akan membuat kumpulan sumber untuk setiap tempat yang kami sokong:

src/main/resources/mailMessages_xx_YY.properties

Oleh kerana FreeMarker mencadangkan penyetempatan dengan menduplikasi templat , kita tidak perlu mengkonfigurasi sumber mesej di sana.

6. Kandungan Templat Thymeleaf

Seterusnya, mari kita lihat fail template-thymeleaf.html :

Seperti yang dapat dilihat, kami telah menggunakan notasi Thymeleaf, iaitu, $ {…} untuk pemboleh ubah dan # {…} untuk rentetan yang dilokalkan .

Oleh kerana mesin templat dikonfigurasi dengan betul, sangat mudah untuk menggunakannya: Kami hanya akan membuat objek Konteks yang mengandungi pemboleh ubah templat (diteruskan sebagai Peta di sini).

Kemudian, kami akan meneruskannya ke kaedah proses bersama dengan nama templat:

@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 perkara yang sama dengan FreeMarker.

7. Kandungan Templat FreeMarker

Seperti yang dapat dilihat, sintaks FreeMarker lebih mudah, tetapi sekali lagi ia tidak menguruskan rentetan setempat. Jadi, inilah versi Bahasa Inggeris:

Hi ${recipientName}

${text}

Regards,

${senderName} at Baeldung

Kemudian, kita harus menggunakan kelas FreeMarkerConfigurer untuk mendapatkan fail templat, dan akhirnya, FreeMarkerTemplateUtils untuk menyuntik data dari Peta kami :

@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, kami akan melihat cara menambahkan logo ke tandatangan e-mel kami.

8. E-mel Dengan Imej Terbenam

Oleh kerana sangat biasa memasukkan gambar dalam e-mel HTML, kita akan melihat cara melakukannya menggunakan lampiran CID.

Perubahan pertama berkenaan dengan kaedah sendHtmlMessage . Kita harus menetapkan MimeMessageHelper sebagai pelbagai bahagian dengan benar pada argumen kedua pembina:

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

Kemudian, kita mesti mendapatkan fail gambar sebagai sumber. Kami boleh menggunakan anotasi @Value untuk ini:

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

Perhatikan bahawa fail mail-logo.png ada di direktori src / main / resources .

Kembali ke kaedah sendHtmlMessage , kami akan menambahkan resourceFile sebagai lampiran sebaris , untuk dapat merujuknya dengan CID:

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

Akhirnya, gambar mesti dirujuk dari kedua-dua e-mel Thymeleaf dan FreeMarker menggunakan notasi CID :

9. Kesimpulannya

Dalam artikel ini, kami telah melihat cara menghantar e-mel Thymeleaf dan FreeMarker, termasuk kandungan HTML yang kaya.

Sebagai kesimpulan, sebahagian besar karya berkaitan dengan Spring; oleh itu, penggunaan satu atau yang lain agak serupa untuk keperluan sederhana seperti menghantar e-mel .

Seperti biasa, kod sumber penuh contoh boleh didapati di GitHub.