Verwenden von ThymeLeaf- und FreeMarker-E-Mail-Vorlagen mit Spring

1. Übersicht

In unserem vorherigen Artikel haben wir gesehen, wie Sie mit Spring Text-E-Mails schreiben und senden können.

Es ist aber auch möglich, Spring Template Engines zu verwenden, um schöne HTML-E-Mails mit dynamischem Inhalt zu schreiben .

In diesem Tutorial lernen wir, wie man es mit dem berühmtesten von ihnen macht: Thymeleaf und FreeMarker .

2. Spring HTML Emails

Beginnen wir mit dem Spring Email-Tutorial.

Zunächst fügen wir der EmailServiceImpl- Klasse eine Methode zum Senden von E-Mails mit einem HTML- Text hinzu :

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); }

Wir verwenden MimeMessageHelper , um die Nachricht zu füllen . Der wichtige Teil ist der wahre Wert, der an die setText- Methode übergeben wird: Er gibt den HTML-Inhaltstyp an.

Lassen Sie uns nun sehen, wie Sie diesen htmlBody mit Thymeleaf- und FreeMarker-Vorlagen erstellen.

3. Thymeleaf-Konfiguration

Beginnen wir mit der Konfiguration. Wir können dies in einer Klasse namens EmailConfiguration isolieren .

Zunächst sollten wir einen Vorlagenauflöser bereitstellen, um das Verzeichnis der Vorlagendateien zu finden .

3.1. Vorlagen als Klassenpfadressourcen

Vorlagendateien können innerhalb der JAR-Datei versendet werden. Dies ist der einfachste Weg, um den Zusammenhalt zwischen Vorlagen und ihren Eingabedaten aufrechtzuerhalten.

Um Vorlagen aus der JAR zu finden, verwenden wir den ClassLoaderTemplateResolver . Unsere Vorlagen befinden sich im Hauptverzeichnis / resources / mail-templates. Daher legen wir das Präfix- Attribut relativ zum Ressourcenverzeichnis fest :

@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. Vorlagen aus dem externen Verzeichnis

In anderen Fällen möchten wir möglicherweise Vorlagen ändern, ohne sie neu erstellen und bereitstellen zu müssen . Um dies zu erreichen, können wir stattdessen die Vorlagen in das Dateisystem einfügen.

Es kann nützlich sein, diesen Pfad in application.properties zu konfigurieren, damit wir ihn für jede Bereitstellung ändern können. Auf diese Eigenschaft kann mit der Annotation @Value zugegriffen werden :

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

Wir übergeben diesen Wert dann an einen FileTemplateResolver anstelle des ClassLoaderTemplateResolver in unserer thymeleafTemplateResolver- Methode:

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

3.3. Konfigurieren Sie die Thymeleaf Engine

Der letzte Schritt besteht darin, die Factory-Methode für die Thymeleaf-Engine zu erstellen. Wir müssen der Engine mitteilen, welchen TemplateResolver wir ausgewählt haben, den wir über einen Parameter in die Bean Factory-Methode einfügen können:

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

Hier wird der zuvor erstellte Resolver von Spring automatisch in die Factory-Methode der Template-Engine eingefügt.

4. FreeMarker-Konfiguration

Auf die gleiche Weise wie Thymeleaf konfigurieren wir in der EmailConfiguration- Klasse den Vorlagenauflöser für FreeMarker-Vorlagen (.ftl ) :

Dieses Mal wird der Speicherort der Vorlagen in der FreeMarkerConfigurer- Bean konfiguriert .

4.1. Vorlagen im Klassenpfad

Hier haben wir die gleichen Optionen wie für Thymeleaf. Konfigurieren wir Vorlagen als Klassenpfadressourcen:

@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. Vorlagen im Dateisystem

Um Vorlagen von einem anderen Pfad im Dateisystem aus zu konfigurieren, müssen Sie die TemplateLoader- Instanz ersetzen :

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

5. Lokalisierung mit Thymeleaf und FreeMarker

Um Übersetzungen mit Thymeleaf zu verwalten, können wir der Engine eine MessageSource- Instanz angeben :

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

Dann würden wir Ressourcenpakete für jedes von uns unterstützte Gebietsschema erstellen:

src/main/resources/mailMessages_xx_YY.properties

Da FreeMarker die Lokalisierung durch Duplizieren der Vorlagen vorschlägt , müssen wir die Nachrichtenquelle dort nicht konfigurieren.

6. Inhalt der Thymeleaf-Vorlagen

Schauen wir uns als nächstes die Datei template-thymeleaf.html an :

Wie zu sehen ist, haben wir die Thymeleaf-Notation verwendet, dh $ {…} für Variablen und # {…} für lokalisierte Zeichenfolgen .

Da die Vorlagen-Engine korrekt konfiguriert ist, ist ihre Verwendung sehr einfach: Wir erstellen lediglich ein Kontextobjekt , das Vorlagenvariablen enthält (hier als Map übergeben ).

Dann übergeben wir es zusammen mit dem Vorlagennamen an die Prozessmethode :

@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); }

Lassen Sie uns nun sehen, wie Sie mit FreeMarker dasselbe tun.

7. Inhalt der FreeMarker-Vorlagen

Wie zu sehen ist, ist die Syntax von FreeMarker einfacher, verwaltet jedoch auch hier keine lokalisierten Zeichenfolgen. Also, hier ist die englische Version:

Hi ${recipientName}

${text}

Regards,

${senderName} at Baeldung

Dann sollten wir die FreeMarkerConfigurer- Klasse verwenden, um die Vorlagendatei abzurufen, und schließlich FreeMarkerTemplateUtils , um Daten aus unserer Map einzufügen :

@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); }

Um weiter zu gehen, erfahren Sie, wie Sie unserer E-Mail-Signatur ein Logo hinzufügen.

8. E-Mails mit eingebetteten Bildern

Da es sehr häufig vorkommt, Bilder in eine HTML-E-Mail aufzunehmen, werden wir anhand eines CID-Anhangs sehen, wie dies funktioniert.

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. Fazit

In diesem Artikel haben wir gesehen, wie Sie Thymeleaf- und FreeMarker-E-Mails senden, einschließlich umfangreicher HTML-Inhalte.

Zusammenfassend lässt sich sagen, dass sich die meisten Arbeiten auf den Frühling beziehen. Daher ist die Verwendung des einen oder anderen für einen einfachen Bedarf wie das Senden von E-Mails ziemlich ähnlich .

Wie immer finden Sie den vollständigen Quellcode der Beispiele auf GitHub.