Java has been ranking as one of the most popular web programming languages for many years. In this tutorial, we will demonstrate how to send HTML emails in Java using its native functionality, and also review several popular libraries.
The main option is to use a Java API for sending and receiving emails via SMTP, POP3, and IMAP. It is implemented as an optional package compatible with any operating system. At the same time, Jakarta Mail is supplied as a part of Jakarta EE and Java EE platforms. In the earlier releases, the mail package was titled “JavaMail API”. However, since July 2019, the Java software has been further developed by the Eclipse Foundation. This is why the email package also got the new name. All main classes and properties are the same for both JavaMail and Jakarta Mail.
Jakarta Mail (JavaMail) basics
To start working with Jakarta Mail, first of all, you should insert jakarta.mail.jarfile
into your CLASSPATH environment. You can download it from the Jakarta Mail project page on GitHub.
Besides, you can find Jakarta Mail jar files in the Maven repository and add them to your environment with Maven dependencies:
<dependencies>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
To build messages with Jakarta Mail, you will need to learn its classes and properties first.
Before we move to code, let’s review core classes and properties, which are most frequently used for building and sending messages with Jakarta Mail.
For example, Message class (javax.mail.Message)
is an abstract class for actually building an email message. Its Mime Message (javax.mail.internet.MimeMessage)
subclass and its main methods are commonly used:
setFrom(Address[ ] addresses)
sets the “From” header field
public void addFrom(Address[ ] addresses)
addRecipients(Message.RecipientType type, String addresses)
adds the given address to the recipient type
public void addRecipient(Message.RecipientType type, Address[ ] addresses)<br>Message.RecipientType.TO “To”<br>Message.RecipientType.CC “Cc”<br>Message.RecipientType.BCC “Bcc”<br>MimeMessage.RecipientType.NEWSGROUPS “Newsgroups”
To learn more about classes and properties, as well as get a detailed guide on using Jakarta Mail, refer to our Jakarta Mail Tutorial.
Here, we will quickly review sending emails via SMTP and adding an HTML part.
Simple Jakarta Mail message via an SMTP server
First of all, we need to define who sends what to who. So, use the SendEmail
public class and set “from” and “to” email addresses and add the subject. With javax.mail.PasswordAuthenticationclass
we will be able to require password authentication to send a message via SMTP server.
In the properties method, we will add the necessary SMTP settings and then create a mail Session object. Afterward, you can create a Message using the MimeMessage
.
Finally, send your message with the Transport
object.
Don’t forget to add Exceptions. This class enables you to get details on possible errors along with an understanding of how to debug them. The main one is MessagingException
. It can be used within javax.mail
, javax.mail.internet
, and javax.mail.search
packages. For example, AddressException
for javax.mail.internet
will be thrown if you offered a wrongly formatted address.
How to test emails in Java?
For testing email sending from Java, we will use Mailtrap, an online tool, which helps test, review, and analyze emails sent from dev, QA, or staging environments, without the risk of spamming your customers or colleagues. Once you have tested and verified that everything works properly, change settings for the server you use in production.
Input:
package com.example.smtp;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class SendEmail {
public static void main(String[] args) {
// Put recipient’s address
String to = "test@example.com";
// Put sender’s address
String from = "from@example.com";
final String username = "1a2b3c4d5e6f7g";//username generated by Mailtrap
final String password = "1a2b3c4d5e6f7g";//password generated by Mailtrap
// Paste host address from the SMTP settings tab in your Mailtrap Inbox
String host = "smtp.mailtrap.io";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");//it’s optional in Mailtrap
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", "2525");// use one of the options in the SMTP settings tab in your Mailtrap Inbox
// Get the Session object.
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
// Set From: header field
message.setFrom(new InternetAddress(from));
// Set To: header field
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
// Set Subject: header field
message.setSubject("My first message with JavaMail");
// Put the content of your message
message.setText("Hi there, this is my first message sent with JavaMail");
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Output:
Sending HTML email with images
To send an HTML email, you should perform the same steps as for sending a simple text message, with only SendHTMLEmail
class instead of just SendEmail. Also, you need to set content to the MimeMessage.setContent(Object, String)
and indicate text/html type.
To add an image to your HTML email in Jakarta Mail, you can choose any of three regular methods: CID, base64 image, or linked image.
To embed a CID image, you need to create a MIME multipart/related message:
Multipart multipart = new MimeMultipart("related");
MimeBodyPart htmlPart = new MimeBodyPart();
//add reference to your image to the HTML body <img src="cid:some-image-cid" alt="img" />
htmlPart.setText(messageBody, "utf-8", "html");
multipart.addBodyPart(htmlPart);
MimeBodyPart imgPart = new MimeBodyPart();
// imageFile is the file containing the image
imgPart.attachFile(imageFile);
// or, if the image is in a byte array in memory, use
// imgPart.setDataHandler(new DataHandler(
// new ByteArrayDataSource(bytes, "image/whatever")));
imgPart.setContentID("<some-image-cid">");
multipart.addBodyPart(imgPart);
message.setContent(multipart);
The simplest way to add an image is just linking to the image hosted on some external server. Refer to your image as a link in the HTML body with an img
tag:
<img src="/wp-content/uploads/2018/11/blog/-illustration-email-embedding-images.png" alt="img" />
Full code example:
package com.example.smtp;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class SendHTMLEmail {
public static void main(String[ ] args) {
String to = "johndoe@gmail.com";
String from = "yourmail@example.com";
final String username = "1a2b3c4d5e6f7g";//generated by Mailtrap
final String password = "1a2b3c4d5e6f7g";//generated by Mailtrap
String host = "smtp.mailtrap.io";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", "2525");
// Get the Session object.
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
// Create a default MimeMessage object.
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
message.setSubject("My HTML message");
// Put your HTML content using HTML markup
message.setContent(
"<p> The text and the <strong>image</strong>
<img src="/wp-content/uploads/2018/11/blog/-illustration-email-embedding-images.png" alt="img" /> "
,
"text/html");
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
In Mailtrap, you can also check the raw data of your message as well as its HTML source on separate tabs. If you would like your message to contain both HTML and plain text, you need to build it using a MimeMultipart(“alternative”) object
. You should create two different parts manually and insert them separately: text/plain body part as the first part in the multipart the text/html body part as the second one.
Need More Options?
We have guided you through the main Jakarta Mail use cases and options. Should you experience any difficulties in installing, implementing, or using this package, refer to the Jakarta Mail FAQ.
Constructing transactional emails to send from your Java app with the Jakarta Mail API does takes time. Alternatively, you can consider options for simplified email sending in Java.
Spring Framework
Spring email infrastructure is built on top of the JavaMail API. It has a quite similar structure and logic. The main email package in Spring is org.springframework.mail
while MIME features can be used with the help of org.springframework.mail.javamail.MimeMessagePreparator.
Let’s review a simple example.
Start with dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
Set up an SMTP server:
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.mailtrap.io");
mailSender.setPort(2525);
mailSender.setUsername("1a2b3v4d5e6f7g");
mailSender.setPassword("1a2b3v4d5e6f7g");
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");
return mailSender;
}
Simple email
@Component
public class EmailServiceImpl implements EmailService {
@Autowired
public JavaMailSender emailSender;
public void sendSimpleMessage(
String to, String subject, String text) {
...
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
...
}
}
Apache Commons Email
Apache commons email is also built on top of JavaMail API. It looks much simpler and supports all the features you need to build and design your email messages (HTML, images, attachments, and templates). We are not going to go deep into detail here, we’re just giving an idea of how a basic email should look.
Maven Dependency
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
App.java
package app;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
public class App {
public static void main(String[] args) throws EmailException {
HtmlEmail mail = new HtmlEmail();
mail.setHostName("smtp.mailtrap.io");
mail.setSmtpPort(2525);
mail.setAuthenticator(new DefaultAuthenticator("1a2b3c4d5e6f7g", "1a2b3c4d5e6f7g"));
mail.setFrom("from@example.com", "From");
mail.addTo("to@example.com", "To");
mail.setSubject("Apache Commons email test");
mail.setHtmlMsg("<p style='font-size:16px;color:green'>Here is your example</p>");
mail.send();
}
}
As you can see, it does simplify email sending. Apache Commons is also used as a base for other email wrappers. For example, mailR, for sending emails from R, or Play Framework.
Simple Java Mail
Simple Java Mail is one of the simplest libraries ever – in fact, it is a wrapper around the JavaMail (Jakarta Mail) API.
Simple Java Mail mitigates the use of numerous Java email classes and properties. At the same time, it is full-featured, with a support for HTML, images, and attachments, as well as templates. It is secure and reliable, as it allows for the signing of emails with DKIM and uses S/MIME encryption. The library is regularly updated and has a comprehensive set of code samples.
Compare the following code with other Java-related examples:
<dependency>
<groupId>org.simplejavamail</groupId>
<artifactId>simple-java-mail</artifactId>
<version>6.0.3</version>
</dependency>
Email email = EmailBuilder.startingBlank()
.from("From", "from@example.com")
.to("To", "to@example.com")
.to("You too", "you@example.com")
.withSubject("Simple Java Mail testing!")
.withPlainText("Looks like it’s really simple!")
.buildEmail();
MailerBuilder
.withSMTPServer("smtp.mailtrap.io", 2525, "1a2b3c4d5e6f7g", "1a2b3c4d5e6f7g")
.withTransportStrategy(TransportStrategy.SMTPS);
.buildMailer()
.sendMail(email);
Final words
Adding email sending functionality to your Java app is not the easiest task. You will need to learn and experiment, try and fail. Luckily, there are some easier alternatives like Simple Java Mail. We are sure that after reading this post you have an idea for where to start to create beautiful emails that really work, and send them from your Java app. Just don’t forget to work in a development environment while experimenting and thoroughly test everything before you move to production!
I hope you enjoyed reading this piece that was originally published by Mailtrap Blog in an in-depth tutorial on sending emails in Java.
Top comments (1)