Building a Java email service with Spring Mail and Thymeleaf
Email remains one of the most reliable channels for transactional communication, from order confirmations to password resets. For Java developers working across industries from retail to logistics, a well-architected email layer reduces friction between the backend and the inbox. With Spring Mail and Thymeleaf, teams can send rich HTML messages while keeping the templates maintainable and reusable.
Many Australian businesses rely on automated emails for invoicing with ATO-compliant receipts and ABN details, shipping notifications that flow out of Australia Post integrations, and appointment reminders that respect local timezones like AEST and AEDT. A clean Java implementation makes these workflows easier to test, audit, and extend when the business grows across states and territories.
Setting up the Spring Boot project
Start by adding the right starters to a Maven or Gradle build. The dependency spring-boot-starter-mail bundles the JavaMail API and Spring's abstraction layer, while spring-boot-starter-thymeleaf gives you the template engine out of the box. For more control over HTML rendering, include spring-boot-starter-web so you can reuse your existing MVC configuration.
In your application.properties, configure the SMTP host. Many Australian projects route through SendGrid, Mailgun, or Amazon SES, each offering data centres in Sydney that keep latency low for local recipients. Define properties such as spring.mail.host, spring.mail.port, spring.mail.username, and spring.mail.password, ideally pulled from environment variables or a secrets manager rather than committed source files.
Choosing between mail sending approaches
| Approach | Template support | Testing ease | Best suited for |
|---|---|---|---|
| Raw JavaMail API | Manual string concatenation | Difficult | Legacy codebases |
| Spring Mail with SimpleMailMessage | Plain text only | Easy | System alerts |
| Spring Mail with MimeMessageHelper | Manual HTML strings | Moderate | Small projects |
| Spring Mail with Thymeleaf | Full HTML templates | Strong | Production transactional email |
| Spring Mail with Pebble or Freemarker | Full HTML templates | Strong | Multi-tenant platforms |
The combination of Spring Mail and Thymeleaf scales well because templates live under src/main/resources/templates/email/ and can be versioned, reviewed, and reused across customer, admin, and partner flows without touching Java code.
Designing Thymeleaf templates for email
Thymeleaf works seamlessly outside a web controller. Inject the SpringTemplateEngine and use templateEngine.process("email/order-confirmation", context) to render the body as a String. The Context object accepts variables such as customer name, order number, total in AUD, and shipping ETA pulled from a warehouse system.
Keep styles inline. Most clients including Outlook strip <style> blocks, so write attributes like style="font-family: Arial, sans-serif; color: #333;" directly on elements. Use tables for layout when the message must render correctly across Gmail, Apple Mail, and the older Outlook versions still common in Australian corporate environments.
Building the email service layer
Encapsulate the send logic in a dedicated service annotated with @Service. Inject JavaMailSender, SpringTemplateEngine, and a configured ResourceLoader for inline images such as a company logo. Wrap each send in a MimeMessageHelper so you can mix plain text, HTML, attachments, and embedded resources in one call.
For reliability, log every send with the recipient domain, template name, and a correlation ID. Privacy guidance from the OAIC encourages minimal personal data retention, so avoid logging full email addresses or order details in plaintext logs. Where possible, route transactional mail through a provider with an Australian presence to keep routing within the country and simplify data residency discussions.
Working with local integrations and timezones
Java's ZonedDateTime makes it straightforward to render times in Australia/Sydney, Australia/Melbourne, or Australia/Perth. Store all timestamps in UTC, then convert at render time. This avoids the confusion that arrives each October when AEDT kicks in and customers receive a "yesterday's" invoice stamped with the wrong day.
When integrating with Australia Post, Afterpay, or local payment gateways such as Stripe Australia, send a confirmation email only after the upstream service returns a success status. Use Spring's @Async or a dedicated queue such as RabbitMQ to keep the user response fast, especially during checkout when page latency has a direct impact on conversion.
Testing, security, and operational tips
Validate templates by rendering them against a sample context and asserting the output contains expected fragments. Tools like GreenMail combined with Wiser let you assert that messages reach an in-memory SMTP server without actually sending mail. For staging environments, use a sandboxed inbox through Mailtrap or a provider's test mode so QA can inspect rendered emails across devices.
Rotate SMTP credentials regularly and bind them to specific IP addresses when your provider allows it. SPF, DKIM, and DMARC records should be configured on your example.com.au domain so messages reach inboxes rather than spam folders, particularly important when sending to government or finance recipients who enforce strict filtering.
Practical recommendations for any team shipping transactional email from Australia
- Store every transactional template under a versioned
email/directory and review changes through pull requests. - Render all timestamps in the recipient's local timezone using
ZoneId.of("Australia/Sydney")as a default. - Send through a provider with a Sydney point of presence to minimise delivery time and meet local data expectations.
- Keep CSS inline and structure layouts with tables for predictable rendering across Outlook and older corporate clients.
- Log only the metadata you need: template name, message ID, recipient domain, and send status.
- Verify DKIM, SPF, and DMARC alignment on your sending domain before going live.
- Write integration tests with GreenMail or MailHog to catch template regressions before they reach customers.