Choosing the right email delivery service provider is very crucial for any business. With a good provider, you will always have the confidence that the emails reach the recipient. In spite of that, this does not apply to many providers. As a result, the delivery of the email is not guaranteed or might take very long. In this tutorial, you will learn how to send emails in Spring Boot using Postmark.
Postmark is an email delivery service that ensures your emails get to your inbox. As a matter of time, it takes 5 to 10 seconds for the emails to reach your inbox. This means that the recipient does not have to wait for the email as the delivery is immediate. Let’s get started with the implementation of Postmark.
Prerequisites
- Knowledge of Java programming language.
- Java development kit(JDK8) and above.
- Postmark account – Create an account using your work email. The work email will be your Sender’s Signature to send from a specific email.
- IntelliJ IDEA community edition – Free code editor for the Java programming language.
Create a new project
To create a new project, Go to Spring initializr to provide the project details. Select the respective sections as shown below.
- Project – Maven
- Language – Java
- Spring Boot – 3.x.x, The version of Spring Boot will vary depending on the time you are reading this article. As a result, the value of x will be the latest version of Spring Boot.
In the Project Metadata section, enter the respective sections as shown below.
- Group – com.javawhizz
- Artifact – sendEmail
- Name – sendEmail
- Description – Send emails in Spring Boot using Postmark
- Package name – com.javawhizz.sendEmail
- Packaging – Jar
- Java – 17
Next, click the ADD DEPENDENCIES button and add the following dependencies.
- Spring Web – Supports the development of web applications.
- Lombok – Assist in the generation of helper methods.
- Validation – Adds constraints to fields to ensure the data entered by the user is correct.
- Thymeleaf – Templating engine for the Java programming language.
If you have entered all the details as provided in the previous sections. The project structure and dependencies should be as shown below.

Click on the GENERATE button to download a zipped file of your project. Now unzip and import the project in IntelliJ. Before continuing, you should give the application some time to download the dependencies.
Add Postmark dependency
Copy and paste the following code into the pom.xml file. Use the command CTRL+SHIFT+O to reload the Maven changes. As a result, this will download the Postmark dependency and add it to the project’s classpath.
<!-- https://mvnrepository.com/artifact/com.postmarkapp/postmark --> <dependency> <groupId>com.postmarkapp</groupId> <artifactId>postmark</artifactId> <version>1.10.21</version> </dependency>
Create the project sub-packages
You should organize the classes in your project based on their responsibilities. As a result, the code will be easy to navigate and make changes in the future. After importing the project into IntelliJ. Create the following sub-packages under the folder src/main/java/com/javawhizz/sendEmail.
- config
- controller
- model
- service
Add Postmark API key
Open the file named application.properties under the folder src/main/resources. Copy and paste the following property into the file.
postmark.api.secretKey=YOUR_API_KEY
Configure the API key
Create a file named ApiClientConfig.java under the config folder. Copy and paste the following code into the file.
package com.javawhizz.sendEmail.config; import com.postmarkapp.postmark.Postmark; import com.postmarkapp.postmark.client.ApiClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ApiClientConfig { @Value("${postmark.api.secretKey}") private String secretKey; @Bean public ApiClient apiClient(){ return Postmark.getApiClient(secretKey); } }
Postmark uses ApiClient
to send an email. To create an instance of this class, create a @Bean
definition that returns ApiClient
.
Inside the bean method definition, call Postmark.getApiClient()
to return an ApiClient
. Note that the getApiClient()
method expects the API key as the argument.
Next, inject the API key using @Value
annotation, then pass the key as the argument of the method. As a result, you only need to inject ApiClient
when sending an email.
Create a message DTO
Create a file named CustomMessage.java under the model package. Next, Copy and paste the following code into the file.
package com.javawhizz.sendEmail.model; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @NoArgsConstructor public class CustomMessage { @Email @NotBlank private String to; @NotBlank @Size(min = 10, max = 200) private String subject; @NotBlank @Size(min = 10, max = 200) private String message; }
Add the @Getter
and @Setter
annotations to the class to generate getter and setter methods. You should also add the @NoArgsContructor
to assist in creating empty objects.
This class represents the details of the message to send to the recipient. With regard to the fields, they represent the recipient’s data. The first field is for the recipient’s email, the second is for the context of the email, and the last is for the email body.
To add constraints to the fields, you should also add the field annotations. As a result, this will verify every user input to ensure the fields adhere to the constraints. The following description explains the constraints added by each annotation.
- @Email – Checks for the correct format of the email.
- @NotBlank – The field should not be null and should not have whitespace.
- @Size – The length of the field must be between the least and highest values inclusive.
Create an email service interface
Create a file named EmailService.java under the service package. Next, copy and paste the following code into the file.
package com.javawhizz.sendEmail.service; import com.javawhizz.sendEmail.model.CustomMessage; import com.postmarkapp.postmark.client.ApiClient; public interface EmailService { Boolean sendEmail(ApiClient client, CustomMessage customMessage); }
The method sendEmail()
will assist you in isolating the controller from the logic to send an email. In general, when sending an email, you only need to inject the EmailService
into the controller. Let’s put in place the implementation of the interface.
Implement the email service interface
Create a file named EmailServiceImpl.java under the service package. Next, copy and paste the following code into the file.
package com.javawhizz.sendEmail.service; import com.javawhizz.sendEmail.model.CustomMessage; import com.postmarkapp.postmark.client.ApiClient; import com.postmarkapp.postmark.client.data.model.message.Message; import com.postmarkapp.postmark.client.exception.PostmarkException; import org.springframework.stereotype.Service; import java.io.IOException; @Service public class EmailServiceImpl implements EmailService{ private static final String FROM = "info@javawhizz.com"; @Override public Boolean sendEmail(ApiClient client, CustomMessage customMessage) { boolean isMessageSent = false; Message message = new Message( FROM, customMessage.getTo(), customMessage.getSubject(), """ <!doctype html> <html lang="en"> <head> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous"> </head> <body> <p>%s</P <div class="card"> <div class="card-body"> <h5 class="card-title">JavaWhizz</h5> <p class="card-text"> In this tutorial you will learn how to send emails in Spring Boot using Postmark </p> <p class="card-text"> <small class="text-body-secondary">Last updated 3 mins ago </small> </p> </div> <img src="https://res.cloudinary.com/javawhizz/image/upload/v1690791222/Send_emails_in_Spring_Boot_using_Postmark_cytdkl.png" class="card-img-bottom" alt="..."> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script> </body> </html> """.formatted(customMessage.getMessage()) ); message.setMessageStream("announcements"); try { if (client.deliverMessage(message) .getMessageId() != null) isMessageSent = true; } catch (PostmarkException | IOException e) { throw new RuntimeException(e); } return isMessageSent; } }
Start by defining your sender signature as a class variable. By default, this is the email account that you used to create a Postmark account.
When sending the email the sender’s signature represents the email FROM
the sender. Next, create a new instance of Messag
e then pass the expected arguments. The expected arguments are the values CustomMessage
passed to the sendEmail()
method.
To send a custom template of your email, add the HTML body as the third parameter. You should also include the email body in the template. To achieve this, add a paragraph in the template with the text %s
to format the string.
Next, call the method formatted()
on the String then pass the method getMessage()
as the argument. As a result, the string returned by the method will be the text of the paragraph.
Postmark uses streams to group different types of emails. To set a stream for this email, call the setMessageStream()
method from the message object. Next, pass the String announcements
as the argument of the method.
The method variable named isMessageSent
tracks the status of the sendEmail()
method. Before sending any message, the value of the variable is false
. After sending a message the value of the variable changes to true
. As a result, the method will return false
if the message is not delivered and true
otherwise.
To send a message call the deliverMessage()
method from the client object. Next, pass the message object as the argument of the method.
On successful email delivery, Postmark returns a response containing information about the email. One of the responses returned is the message ID. As a result, you can change the return value of the method depending on whether the message ID has a value or null.
Create the email controller
Create a file named EmailController.java under the controller package. Copy and paste the following code into the file.
package com.javawhizz.sendEmail.controller; import com.javawhizz.sendEmail.model.CustomMessage; import com.javawhizz.sendEmail.service.EmailService; import com.postmarkapp.postmark.client.ApiClient; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; @Controller @RequiredArgsConstructor public class EmailController { private final ApiClient apiClient; private final EmailService emailService; @GetMapping("/") public String home(Model model){ model.addAttribute("customMessage", new CustomMessage()); model.addAttribute("success", false); return "index"; } @PostMapping("/send-email") public String sendEmail(@ModelAttribute @Valid CustomMessage customMessage, BindingResult bindingResult, Model model){ if (bindingResult.hasErrors()){ return "index"; } if (emailService.sendEmail(apiClient, customMessage)){ model.addAttribute("customMessage", customMessage); model.addAttribute("success", true); return "index"; } model.addAttribute("customMessage", new CustomMessage()); model.addAttribute("success", false); return "index"; } }
To create a controller class, you only need to add the @Controller
annotation to the class. Next, add the @RequiredArgsContructor
to the class. This annotation when assist in creating constructors for the final fields.
Next, inject the ApiClient
and the EmailService
which you will use to send a message.
When you first access your application, the method named home()
gets called. The method returns the HTML file named index.html which contains a form to send an email.
Once you enter the email details and press the send button, the request goes to the sendEmail() method. To send an email, call the sendEmail()
method of EmailService
and pass the arguments.
The arguments for the method include the injected ApiClient
and the CustomMessage
. If the delivery of the email is successful, the method shows a success message alert on the same page.
The model attribute named success stores the status of the email delivery. As a result, the value changes depending on whether the method returns true
or false
.
Create the email page
Create a file named index.html under the folder src/main/resources/templates. Copy and paste the following code into the file.
<!doctype html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Bootstrap demo</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-12"> <form class="mb-3" th:object="${customMessage}" th:action="@{/send-email}" method="post"> <h2>Announce a new tutorial</h2> <div class="mb-3"> <label for="to" class="form-label">To</label> <input type="email" th:field="*{to}" class="form-control" id="to" aria-describedby="emailHelp"> <p th:if="${#fields.hasErrors('to')}" th:errors="*{to}" style="color: red"/> </div> <div class="mb-3"> <label for="subject" class="form-label">Subject</label> <input type="text" th:field="*{subject}" class="form-control" id="subject"> <p th:if="${#fields.hasErrors('subject')}" th:errors="*{subject}" style="color: red"/> </div> <div class="form-floating mb-3"> <textarea class="form-control" th:field="*{message}" placeholder="Announce a new tutorial" id="message"></textarea> <label for="message">Message</label> <p th:if="${#fields.hasErrors('message')}" th:errors="*{message}" style="color: red"/> </div> <button type="submit" class="btn btn-primary">Send</button> </form> <div class="container alert alert-success" th:if="${success}"> <div class="row "> <div class="col-md-12 d-flex justify-content-center align-items-center"> <div class="card mt-3"> <div class="card-body"> <button type="button" class="btn btn-success"> Message sent successfully. Check your inbox! </button> </div> </div> </div> </div> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script> </body> </html>
This is the form loaded when you first access the application. Note that it contains the three fields in the custom message and uses Thymeleaf as a template engine.
The th
tags are Thymeleaf expressions and they will get processed on the server to bind the form data to an object. Once you click on the send button, the /send-email
mapping will handle the request.
Any errors entered in the form get checked by the hasErrors()
method. As a result, the error also gets displayed in a paragraph next to the input field.
Run and test the application
To run the application, use the command SHIFT+F10. If there were no errors in running the application, go to localhost:8080 on your browser to load the email page. As a result, you should see the following page on your browser.

Since you are using Postmark in test mode, you can only send an email to emails of the same domain. In this case, the email used here is sending an email to itself.
To send from other emails in your domain, you need to verify your domain in Postmark. Next, click on the Send button to send the email. If the delivery was successful, you should see the following alert on the same page.

As you can see, the delivery of the message is very fast, if you go to your inbox you will find the email you have sent. The contents of the message should be as shown below.

Conclusion
In this tutorial, you have learned how to send emails in Spring Boot using Postmark. Postmark is one of the fastest email delivery services that you can use in your applications.
Note that there are other email delivery services out there there. Some of these services include SendGrid, SparkPost, Mailgun, Amazon SES, and Mandrill. Feel free to try out one of these services and see which works best for you.
At the moment, play around with Postmarks API to learn how to send and receive emails. You can also try sending an email using their SMTP protocol to check whether the email delivery is also as fast.
Happy Hacking!
0 Comments