Contents
- Dependency
- Sending Email via SMTP
- HTML Email & Headers
- Attachments
- Polling an IMAP Inbox
- Gmail / App Password Config
- Key URI Options
Add camel-mail-starter for Spring Boot. It brings in Jakarta Mail transitively.
<!-- Spring Boot -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-mail-starter</artifactId>
</dependency>
<!-- Standalone Camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mail</artifactId>
</dependency>
Use to("smtp://...") or to("smtps://...") (for TLS). The exchange body becomes the email body. Set recipient, subject, and other metadata as headers using the MailConstants class or their string equivalents.
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mail.MailConstants;
import org.springframework.stereotype.Component;
@Component
public class SmtpRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:sendEmail")
.setHeader(MailConstants.MAIL_REPLY_TO, constant("noreply@example.com"))
.setHeader("To", constant("recipient@example.com"))
.setHeader("Subject", simple("Order ${header.orderId} confirmed"))
.setBody(simple("Hello ${header.customerName},\n\nYour order ${header.orderId} has been confirmed."))
.to("smtps://smtp.example.com:465"
+ "?username=sender@example.com"
+ "&password=secret"
+ "&from=sender@example.com");
}
}
Use smtps:// (port 465) for implicit SSL, or smtp:// with ?security=StartTls (port 587) for STARTTLS. Never use plain smtp:// on port 25 in production.
Send an HTML email by setting the Content-Type header to text/html; charset=UTF-8. Use CC and BCC headers for additional recipients.
from("direct:sendHtmlEmail")
.setHeader("To", constant("user@example.com"))
.setHeader("CC", constant("manager@example.com"))
.setHeader("Subject", constant("Monthly Report"))
.setHeader("Content-Type", constant("text/html; charset=UTF-8"))
.setBody(constant("""
<html>
<body>
<h2>Monthly Report</h2>
<p>Please find the summary below.</p>
</body>
</html>
"""))
.to("smtps://smtp.example.com:465?username=sender@example.com&password=secret&from=sender@example.com");
Add attachments by putting DataHandler objects into the exchange's attachment map via exchange.getMessage().addAttachment(fileName, dataHandler). The Camel Mail component serializes them as MIME multipart attachments automatically.
import jakarta.activation.DataHandler;
import jakarta.activation.FileDataSource;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
@Component
public class MailAttachmentRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:sendWithAttachment")
.setHeader("To", constant("user@example.com"))
.setHeader("Subject", constant("Invoice Attached"))
.setBody(constant("Please find your invoice attached."))
.process(addAttachment("/tmp/invoice.pdf", "invoice.pdf"))
.to("smtps://smtp.example.com:465?username=sender@example.com&password=secret&from=sender@example.com");
}
private Processor addAttachment(String filePath, String fileName) {
return exchange -> {
DataHandler dh = new DataHandler(new FileDataSource(filePath));
exchange.getMessage().addAttachment(fileName, dh);
};
}
}
Use from("imap://...") or from("imaps://...") to poll a mailbox at a fixed interval. Each email becomes a Camel exchange. Set delete=true to delete messages after processing, or unseen=true to only fetch unread messages.
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mail.MailConstants;
import org.springframework.stereotype.Component;
@Component
public class ImapPollRoute extends RouteBuilder {
@Override
public void configure() {
from("imaps://imap.example.com:993"
+ "?username=inbox@example.com"
+ "&password=secret"
+ "&folder=INBOX"
+ "&unseen=true" // only fetch unread messages
+ "&delete=false" // mark as read, don't delete
+ "&delay=30000") // poll every 30 s
.routeId("imap-poller")
.log("New email from: ${header[" + MailConstants.MAIL_FROM + "]} — subject: ${header[" + MailConstants.MAIL_SUBJECT + "]}")
.to("direct:processEmail");
from("direct:processEmail")
.log("Body: ${body}");
}
}
Key headers populated on each consumed email:
| Header | Description |
| MailConstants.MAIL_FROM | Sender address. |
| MailConstants.MAIL_TO | Primary recipient(s). |
| MailConstants.MAIL_SUBJECT | Email subject line. |
| MailConstants.MAIL_REPLY_TO | Reply-To address. |
| MailConstants.MAIL_DATE | Sent date. |
Google requires an App Password (not your regular account password) when logging in via SMTP/IMAP from a third-party app. Generate one under Google Account → Security → 2-Step Verification → App Passwords.
# application.properties — Gmail SMTP via Spring Boot
camel.component.smtps.host=smtp.gmail.com
camel.component.smtps.port=465
camel.component.smtps.username=you@gmail.com
camel.component.smtps.password=${GMAIL_APP_PASSWORD}
// Route using component-level defaults — no credentials in the URI
from("direct:sendGmail")
.setHeader("To", constant("friend@example.com"))
.setHeader("Subject", constant("Hello from Camel"))
.setBody(constant("Sent via Apache Camel + Gmail SMTP"))
.to("smtps://smtp.gmail.com:465?from=you@gmail.com");
# Gmail IMAP polling
camel.component.imaps.host=imap.gmail.com
camel.component.imaps.port=993
camel.component.imaps.username=you@gmail.com
camel.component.imaps.password=${GMAIL_APP_PASSWORD}
| Option | Default | Description |
| username / password | — | Authentication credentials. |
| from | — | Sender (From) address for outgoing mail. |
| folder | INBOX | Mailbox folder to poll (IMAP consumer). |
| unseen | true | Only fetch messages that have not been read. |
| delete | false | Delete messages from the server after consuming. |
| delay | 60000 | Polling interval in milliseconds (consumer). |
| security | — | Set to StartTls for STARTTLS on port 587. |
| fetchSize | -1 (all) | Maximum number of messages fetched per poll. |
| contentType | text/plain | MIME content type for outgoing email body. |
| attachmentsContentTransferEncodingResolver | — | Custom resolver for attachment encoding (Base64, QP, etc.). |