BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ APIs and web

I/O and data

Sending email (JavaMail, Spring Mail)

Applications send email for receipts, resets and alerts through an SMTP server.

๐Ÿ”Ž Unravel this example

At a glance

Mental model

Posting a letter.

What happens, in order
  1. 1Spring: JavaMailSender.send(SimpleMailMessage) for plain text; MimeMessageHelper for HTML, inline images and attachments (helper.addAttachment(name, resource))
  2. 2Connection settings (spring.mail.host, port, username, TLS) are configured, with the password injected from a secret store
  3. 3HTML bodies are usually rendered from a template (Thymeleaf, FreeMarker) so non-developers can edit the text
  4. 4Sending is a network call to a server that may be slow or down, so it belongs in @Async code, a queue or an outbox, not in the request thread or inside a database transaction
Remember
Watch out
Sending synchronously inside a request or transactionHeader injection through unescaped user inputNo retry or failure recordCredentials in source code
Example (highlighted lines explain it)
MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");helper.setTo(user.email());helper.setSubject("Your receipt");helper.setText(templateEngine.process("receipt", context), true);helper.addAttachment("receipt.pdf", new ByteArrayResource(pdf));mailSender.send(message);
  1. line 1 uses MimeMessage, the core of Sending email (JavaMail, Spring Mail)
  2. line 2 uses MimeMessageHelper, the core of Sending email (JavaMail, Spring Mail)
Read the full explanation (about 1 min)

Applications send email for receipts, resets and alerts through an SMTP server. The code builds a message (plain text and HTML, attachments) and hands it to a mail sender, which is slow and unreliable enough to be run in the background.

A mental model

Posting a letter. You write it and drop it at the post office, which may take a while, and a letter can come back as undeliverable days later.

How it works

Spring: JavaMailSender.send(SimpleMailMessage) for plain text; MimeMessageHelper for HTML, inline images and attachments (helper.addAttachment(name, resource)).

Connection settings (spring.mail.host, port, username, TLS) are configured, with the password injected from a secret store.

HTML bodies are usually rendered from a template (Thymeleaf, FreeMarker) so non-developers can edit the text.

Sending is a network call to a server that may be slow or down, so it belongs in @Async code, a queue or an outbox, not in the request thread or inside a database transaction.

Going deeper

Escape or reject line breaks in headers built from user input (subject, recipient). Otherwise attackers inject extra recipients or headers (header injection).

Treat mail as best effort. Record what you intend to send, retry with backoff, and handle bounces. Email providers (SES, SendGrid) with an API and webhooks are more reliable than a raw SMTP relay.

Use TLS (STARTTLS or SMTPS) and authentication; never send passwords or one-time links that stay valid forever by email.

Under the hood

Transport.send opens a socket to the SMTP server, negotiates TLS, authenticates and issues MAIL FROM, RCPT TO and DATA commands, then closes. The sender does not hold a connection pool by default, so each message pays the full handshake unless you use a session transport and batch.

Common mistakes

  • Sending synchronously inside a request or transaction.
  • Header injection through unescaped user input.
  • No retry or failure record.
  • Credentials in source code.

How Unravel recognises it

When you paste code, Unravel looks for these signs of sending email (javamail, spring mail). Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Sending email (JavaMail, Spring Mail)?

Applications send email for receipts, resets and alerts through an SMTP server. The code builds a message (plain text and HTML, attachments) and hands it to a mail sender, which is slow and unreliable enough to be run in the background.

What are the most common mistakes with Sending email (JavaMail, Spring Mail)?

Sending synchronously inside a request or transaction. Header injection through unescaped user input. No retry or failure record. Credentials in source code.

How can I see Sending email (JavaMail, Spring Mail) in real code?

Paste your own Java into Unravel and it will point out where sending email (javamail, spring mail) appears, explain how it works at the detail level you choose, and draw the flow of the code around it.