Message templates in java

Send Email with Thymeleaf template in Spring Boot

In this article, we’ll learn how to compose emails using Thymeleaf template and send emails using spring framework’s JavaMailSender.

Overview

Thymeleaf is a modern sever-side Java template engine. Thymeleaf is mostly used to build elegant HTML templates. Spring boot web MVC provides good integration with Thymeleaf for server-side view development.

We will first use Thymeleaf templates to compose HTML email messages and then we will use spring framework’s JavaMailSender to send email.

Project Setup

For initial setup of your Spring Boot project, you should use Spring Initializr. Choose the Java Mail Sender and Thymeleaf as dependencies.

You can use either Maven or Gradle build tool of your choice:-

Maven Project

pom.xml
    org.springframework.boot   spring-boot-starter-mail      org.springframework.boot   spring-boot-starter-thymeleaf      org.springframework.boot   spring-boot-starter-test   test  

Gradle Project

Click on the below link to generate a Gradle project with pre-selected required dependencies:-

build.gradle
dependencies   // to send email using java Mail and spring framework's JavaMailSender  implementation 'org.springframework.boot:spring-boot-starter-mail'   // to create email templates using Thymeleaf server-side Java template engine  implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'   // to write test class using junit jupiter  testImplementation 'org.springframework.boot:spring-boot-starter-test' > 

Project Structure

A typical project structure for writing an email service looks like this:-

📖springboot-email 📁src 📁main 📁java 📦com.example.email 📦config 📄ThymeleafTemplateConfig 📦model 📄Email 📦service 📄EmailSenderService EmailApplication 📁resources 📁templates 📄welcome-email.htmlapplication.yml pom.xml build.gradle 

Thymeleaf Email Template Configuration

In order to process our email templates, we will configure a SpringTemplateEngine :-

package com.example.email.config;  @Configuration public class ThymeleafTemplateConfig    @Bean  public SpringTemplateEngine springTemplateEngine()   SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();  springTemplateEngine.addTemplateResolver(emailTemplateResolver());  return springTemplateEngine;  >   public ClassLoaderTemplateResolver emailTemplateResolver()   ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();  emailTemplateResolver.setPrefix("/templates/");  emailTemplateResolver.setSuffix(".html");  emailTemplateResolver.setTemplateMode(TemplateMode.HTML);  emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());  emailTemplateResolver.setCacheable(false);  return emailTemplateResolver;  > > 

This template configuration will look for templates in src/main/resources/templates/ folder with .html extension.

Let’s create our welcome email HTML template with Thymeleaf:-

src/main/resources/templates/welcome-email.html
 html xmlns:th="http://www.thymeleaf.org">  head>  title th:remove="all">Template for HTML emailtitle>  meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>  head>  body>  p>  Hello, span th:text="$">Peter Staticspan>!  p>  p th:if="$ 10>">  Wow! You've got a long name (more than 10 chars)!  p>  p>  You have been successfully subscribed to the b>CodingNConceptsb> on  span th:text="$">28-12-2012span>  p>  p>We write on following technologies:-p>  ul th:remove="all-but-first">  li th:each="tech : $" th:text="$">Javali>  li>JavaScriptli>  li>CSSli>  ul>  p>  Regards, br/>  em>The CodingNConcepts Teamem>  p>  body>  html> 

JavaMailSender Configuration

Provide the SMTP (Mail) server configuration in application.yml or application.properties file to initialize JavaMailSender , which we will use to send emails.

application.yml
spring:  mail:  default-encoding: UTF-8  host: smtp.gmail.com  port: 587  username: lahoti.ashish20@gmail.com  password: #gmail_app_password  properties:  mail:  smtp:  auth: true  starttls:  enable: true  debug: true  protocol: smtp  test-connection: false 

Some of the popular SMTP (Mail) server details are as follows:-

Email Host Port Authentication Username Password
Gmail smtp.gmail.com 587 (TLS) true example@gmail.com Generate Gmail App Password
Yahoo smtp.mail.yahoo.com 465 (SSL) or 587 (TLS) true example@yahoo.com Generate Yahoo App Password

If you want to use Gmail or Yahoo server to send email then you need a valid username and password for authentication. You can use your existing email address for e.g. lahoti.ashish20@gmail.com as username but password isn’t the same as your email password. You need to generate an app password from your mail account to use with SMTP (Mail) server.

If you are working in an organization then you might need your organization SMTP server details to configure.

Service to Send Email

Let’s use SpringTemplateEngine to compose email and JavaMailSender to send email in our service class:-

package com.example.email.service;  @Service @RequiredArgsConstructor @Slf4j public class EmailSenderService    private final JavaMailSender emailSender;  private final SpringTemplateEngine templateEngine;   public void sendHtmlMessage(Email email) throws MessagingException   MimeMessage message = emailSender.createMimeMessage();  MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, StandardCharsets.UTF_8.name());  Context context = new Context();  context.setVariables(email.getProperties());  helper.setFrom(email.getFrom());  helper.setTo(email.getTo());  helper.setSubject(email.getSubject());  String html = templateEngine.process(email.getTemplate(), context);  helper.setText(html, true);   log.info("Sending email: <> with html body: <>", email, html);  emailSender.send(message);  > > 

Test Service to Send Email

Now its time to test sending email message composed using welcome-email.html thymeleaf template

@SpringBootTest public class EmailSenderServiceTest    @Autowired  private EmailSenderService emailSenderService;   @Test  public void sendHtmlMessageTest() throws MessagingException   Email email = new Email();  email.setTo("lahoti.ashish20@gmail.com");  email.setFrom("lahoti.ashish20@gmail.com");  email.setSubject("Welcome Email from CodingNConcepts");  email.setTemplate("welcome-email.html");  MapString, Object> properties = new HashMap<>();  properties.put("name", "Ashish");  properties.put("subscriptionDate", LocalDate.now().toString());  properties.put("technologies", Arrays.asList("Python", "Go", "C#"));  email.setProperties(properties);   Assertions.assertDoesNotThrow(() -> emailSenderService.sendHtmlMessage(email));  > > 

Voilà! Message arrived in my mailbox:-

Send Email using Thymeleaf template

Download the complete source code for the examples in this post from github/springboot-email

Ashish Lahoti avatar

Ashish Lahoti is a Software Engineer with 12+ years of experience in designing and developing distributed and scalable enterprise applications using modern practices. He is a technology enthusiast and has a passion for coding & blogging.

Источник

Message Templates

A language-neutral specification for 1) capturing, and 2) rendering, structured log events in a format that’s both human-friendly and machine-readable.

Message Templates

This document explains the reasons message templates are used, and provides a specification of their syntax, capturing behavior, and rendering behavior, to assist in creating implementations for various programming languages and logging interfaces.

A brief history of structured logging APIs

Early application logging, or printf debugging, produced a stream of text describing the events taking place within an application.

log("User %s logged in from %s", username, ipAddress); // -> 2016-05-27T13:02:11.888 User alice logged in from 123.45.67.89 

This worked well for simple applications running on a single computer, and over the years many tools evolved to help support this format in ever-more-complex, and ever-more-distributed applications. Log parsing can extract most of the relevant information from the event above, but considerable effort is required for non-trivial diagnostic scenarios.

At various times, alternatives to text logs have been proposed under the banner of structured logging, which considers log data to be a stream of fully-structured events with key/value properties. Structured log events are much easier to work with in large, complex and distributed applications, because relevant events can be identified using queries over their properties, rather than by regular expressions over a text payload.

The obvious method of recording structured log events, found particularly in languages with terse key/value property syntax, is to encode the event directly as a map of key/value pairs:

log(eventId: "user_logged_in", username: username, ip_address: ipAddress >); // -> // "username": "alice", "ip_address": "123.45.67.89"> 

JSON is used as an example rendering here, but the concept is not tied to a particular representation.

This greatly improves machine-readability, enabling queries like username = ‘alice’ on the raw log stream, but the event itself is not human-friendly. Log events recorded in prose make full use of our language processing and pattern recognition abilities to ease cognition. A long stream of key/value pairs is painful to visually process. Compare the representative output of the two examples above to experience this effect — what’s happening in the second event?

Another approach employs convention to identify properties within a printf -style message:

log("User username=%s logged in from ip_address=%s", username, ipAddress); // -> 2016-05-27T13:02:11.888 User username=alice logged in from ip_address=123.45.67.89 

In principle, this technique benefits from greater readability, but in practice the looseness of the format causes ambiguities when parsing, and inconsistent usage within development teams. Ambiguities arise when a property inserted into the event contains embedded spaces and/or = characters. The lack of a defined grammar (and lack of awareness of the grammar in the logging tool) means developers have no opportunity to validate their use of the syntax – breaking the convention is easy and goes unnoticed.

Finally, niche logging systems like Event Tracing for Windows have taken a middle ground, combining event ids in the log event with a manifest of format specifiers describing how a particular event can be rendered as text. Despite the near-perfect balance of performance, human-friendliness and machine-readability, the effort associated with assigning event ids and managing manifests have an impact on development-time ergonomics that limit the appeal of this system.

All of these issues and shortcomings have kept fully-structured logging from reaching widespread adoption, but the need for it has continued to grow.

Message templates overview

Message templates take the best of all these approaches to provide optimal human-friendliness, perfect machine-readability and excellent development-time ergonomics.

A message template is a format specifier with named holes for event data:

Message templates are unique in that they provide a means of capturing the event, as well as a means of rendering it into human-friendly text.

Logging APIs capture log events by positionally matching arguments with the named holes:

log("User logged in from ", username, ipAddress) // -> // "time": "2016-05-27T13:02:11.888", // "template": "User logged in from ", // "username": "alice", // "ip_address": "123.45.67.89" // > 

An event captured using a message template is not immediately rendered into text unless it is being displayed directly to a user. Instead, the template itself is captured, along with property values for each argument. This is stored in an intermediate representation like JSON for processing.

Because the template remains constant regardless of the actual property values substituted, it is possible to treat the template as an event type that identifies all events from the same template. In this example, log-ins from various users will carry the different username values, but the consistent message template shared by all of them means they can be retrieved as a group.

When the event is displayed to a human user, or searched for text, it is rendered by replacing each of the named holes with the corresponding property:

// -> User alice logged in from 123.45.67.89 

Syntax

A message template is a block of text with embedded holes that name a property to be captured and inserted into the text.

The grammar below is maintained in the messagetemplates/grammar repository; images generated by Railroad Diagram Generator.

Template

Template

Источник

Читайте также:  Php пробелы между разрядами
Оцените статью