Jakarta Mail defines a platform-independent and protocol-independent framework to build mail and messaging applications.
—
Internet Mail support provides comprehensive MIME message creation, multipart handling, internet address management, and header processing for standards-compliant email handling.
The MimeMessage class provides a complete implementation of MIME-formatted email messages.
public class MimeMessage extends Message implements MimePart {
// Constructors
public MimeMessage(Session session);
public MimeMessage(Session session, InputStream is) throws MessagingException;
public MimeMessage(MimeMessage source) throws MessagingException;
// Text content methods
public void setText(String text) throws MessagingException;
public void setText(String text, String charset) throws MessagingException;
public void setText(String text, String charset, String subtype) throws MessagingException;
// Content management
public void setContent(Object o, String type) throws MessagingException;
public void setContent(Multipart mp) throws MessagingException;
// Message preparation
public void saveChanges() throws MessagingException;
public void updateHeaders() throws MessagingException;
// MIME-specific methods
public String getEncoding() throws MessagingException;
public void setDescription(String description) throws MessagingException;
public void setDescription(String description, String charset) throws MessagingException;
// Header management (inherited from MimePart)
public void setHeader(String name, String value) throws MessagingException;
public void addHeader(String name, String value) throws MessagingException;
public void removeHeader(String name) throws MessagingException;
public String[] getHeader(String name) throws MessagingException;
public Enumeration<Header> getAllHeaders() throws MessagingException;
public Enumeration<Header> getMatchingHeaders(String[] names) throws MessagingException;
public Enumeration<Header> getNonMatchingHeaders(String[] names) throws MessagingException;
}import jakarta.mail.*;
import jakarta.mail.internet.*;
// Create MIME message
MimeMessage message = new MimeMessage(session);
// Set basic headers
message.setFrom(new InternetAddress("sender@example.com", "Sender Name"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("recipient@example.com"));
message.setSubject("MIME Message Example", "UTF-8");
// Simple text content
message.setText("Hello, this is a simple text message", "UTF-8");
// HTML content
message.setContent("<h1>Hello</h1><p>This is an HTML message</p>", "text/html; charset=utf-8");
// Custom headers
message.setHeader("X-Priority", "1");
message.setHeader("X-Mailer", "My Mail Client");
// Save changes before sending
message.saveChanges();
Transport.send(message);The InternetAddress class handles RFC822-compliant email addresses with personal names.
public class InternetAddress extends Address implements Cloneable {
// Constructors
public InternetAddress();
public InternetAddress(String address) throws AddressException;
public InternetAddress(String address, boolean strict) throws AddressException;
public InternetAddress(String address, String personal) throws AddressException;
public InternetAddress(String address, String personal, String charset) throws AddressException;
// Static parsing methods
public static InternetAddress[] parse(String addresslist) throws AddressException;
public static InternetAddress[] parse(String addresslist, boolean strict) throws AddressException;
public static InternetAddress[] parseHeader(String addresslist, boolean strict) throws AddressException;
// Static utility methods
public static String toString(Address[] addresses);
public static String toString(Address[] addresses, int used);
// Address components
public String getAddress();
public void setAddress(String address) throws AddressException;
public String getPersonal();
public void setPersonal(String name) throws UnsupportedEncodingException;
public void setPersonal(String name, String charset) throws UnsupportedEncodingException;
// Validation
public void validate() throws AddressException;
public static void validate(Address[] addresses) throws AddressException;
// Address operations
public Object clone();
public boolean equals(Object a);
public int hashCode();
public String toString();
public String toUnicodeString();
}import jakarta.mail.internet.*;
// Simple address creation
InternetAddress simple = new InternetAddress("user@example.com");
// Address with personal name
InternetAddress withName = new InternetAddress("user@example.com", "John Doe");
// Address with Unicode personal name
InternetAddress unicode = new InternetAddress("user@example.com", "José García", "UTF-8");
// Parse address lists
InternetAddress[] addresses = InternetAddress.parse("user1@example.com, John Doe <user2@example.com>");
// Parse with strict validation
try {
InternetAddress[] strict = InternetAddress.parse("invalid-address", true);
} catch (AddressException e) {
System.out.println("Invalid address format: " + e.getMessage());
}
// Convert addresses back to string
String addressList = InternetAddress.toString(addresses);
// Validate addresses
try {
InternetAddress.validate(addresses);
System.out.println("All addresses are valid");
} catch (AddressException e) {
System.out.println("Invalid address found: " + e.getMessage());
}The NewsAddress class handles Usenet newsgroup addresses.
public class NewsAddress extends Address {
// Constructors
public NewsAddress();
public NewsAddress(String newsgroup);
public NewsAddress(String newsgroup, String host);
// Static parsing methods
public static NewsAddress[] parse(String addresslist) throws AddressException;
// Address components
public String getNewsgroup();
public void setNewsgroup(String newsgroup);
public String getHost();
public void setHost(String host);
// Address operations
public String toString();
public boolean equals(Object a);
public int hashCode();
}The MimeMultipart class manages multipart MIME content with multiple body parts.
public class MimeMultipart extends Multipart {
// Constructors
public MimeMultipart();
public MimeMultipart(String subtype);
public MimeMultipart(DataSource ds) throws MessagingException;
// Content management
public void setSubType(String subtype);
public int getCount() throws MessagingException;
public BodyPart getBodyPart(int index) throws MessagingException;
public void addBodyPart(BodyPart part) throws MessagingException;
public void addBodyPart(BodyPart part, int index) throws MessagingException;
public boolean removeBodyPart(BodyPart part) throws MessagingException;
public void removeBodyPart(int index) throws MessagingException;
// Serialization
public void writeTo(OutputStream os) throws IOException, MessagingException;
// Preamble and epilogue
public String getPreamble() throws MessagingException;
public void setPreamble(String preamble) throws MessagingException;
}public class MimeBodyPart extends BodyPart implements MimePart {
// Constructors
public MimeBodyPart();
public MimeBodyPart(InputStream is) throws MessagingException;
public MimeBodyPart(InternetHeaders headers, byte[] content) throws MessagingException;
// Content methods
public void setText(String text) throws MessagingException;
public void setText(String text, String charset) throws MessagingException;
public void setText(String text, String charset, String subtype) throws MessagingException;
public void setContent(Object o, String type) throws MessagingException;
public void setContent(Multipart mp) throws MessagingException;
// File attachment methods
public void attachFile(File file) throws IOException, MessagingException;
public void attachFile(String file) throws IOException, MessagingException;
public void attachFile(File file, String contentType, String encoding) throws IOException, MessagingException;
// Filename methods
public String getFileName() throws MessagingException;
public void setFileName(String filename) throws MessagingException;
// Disposition methods
public String getDisposition() throws MessagingException;
public void setDisposition(String disposition) throws MessagingException;
// Description methods
public String getDescription() throws MessagingException;
public void setDescription(String description) throws MessagingException;
public void setDescription(String description, String charset) throws MessagingException;
}import jakarta.mail.internet.*;
import jakarta.mail.*;
import java.io.File;
// Create multipart message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("sender@example.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@example.com"));
message.setSubject("Multipart Message with Attachment");
// Create multipart container
MimeMultipart multipart = new MimeMultipart("mixed");
// Text part
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("Please find the attached document.", "UTF-8");
multipart.addBodyPart(textPart);
// File attachment
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(new File("document.pdf"));
attachmentPart.setFileName("Important Document.pdf");
attachmentPart.setDisposition(Part.ATTACHMENT);
multipart.addBodyPart(attachmentPart);
// Set multipart content
message.setContent(multipart);
message.saveChanges();
// Alternative: HTML with inline images
MimeMultipart htmlMultipart = new MimeMultipart("related");
// HTML part
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent("<html><body><h1>Hello</h1><img src='cid:image1'></body></html>", "text/html; charset=utf-8");
htmlMultipart.addBodyPart(htmlPart);
// Inline image
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.attachFile(new File("logo.png"));
imagePart.setDisposition(Part.INLINE);
imagePart.setHeader("Content-ID", "<image1>");
htmlMultipart.addBodyPart(imagePart);The InternetHeaders class manages RFC822 message headers.
public class InternetHeaders {
// Constructors
public InternetHeaders();
public InternetHeaders(InputStream is) throws MessagingException;
// Header access
public String[] getHeader(String name);
public String getHeader(String name, String delimiter);
public Enumeration<Header> getAllHeaders();
public Enumeration<Header> getMatchingHeaders(String[] names);
public Enumeration<Header> getNonMatchingHeaders(String[] names);
// Header modification
public void addHeader(String name, String value);
public void setHeader(String name, String value);
public void removeHeader(String name);
// Header operations
public void load(InputStream is) throws MessagingException;
}The HeaderTokenizer class parses RFC822 header values into tokens.
public class HeaderTokenizer {
// Token types
public static final int ATOM = -1;
public static final int QUOTEDSTRING = -2;
public static final int COMMENT = -3;
public static final int EOF = -4;
// Constructors
public HeaderTokenizer(String header);
public HeaderTokenizer(String header, String delimiters);
public HeaderTokenizer(String header, String delimiters, boolean skipComments);
// Token parsing
public Token next() throws ParseException;
public Token peek() throws ParseException;
public String getRemainder();
// Token class
public static class Token {
public int getType();
public String getValue();
}
}import jakarta.mail.internet.*;
// Parse Content-Type header
String contentTypeHeader = "text/html; charset=utf-8; boundary=xyz123";
HeaderTokenizer tokenizer = new HeaderTokenizer(contentTypeHeader, ";");
HeaderTokenizer.Token token = tokenizer.next();
String primaryType = token.getValue(); // "text/html"
while ((token = tokenizer.next()).getType() != HeaderTokenizer.EOF) {
if (token.getType() == HeaderTokenizer.ATOM) {
String param = token.getValue();
// Process parameter
}
}
// Work with InternetHeaders
InternetHeaders headers = new InternetHeaders();
headers.setHeader("Content-Type", "text/plain; charset=utf-8");
headers.addHeader("X-Custom-Header", "custom-value");
// Get all headers
Enumeration<Header> allHeaders = headers.getAllHeaders();
while (allHeaders.hasMoreElements()) {
Header header = allHeaders.nextElement();
System.out.println(header.getName() + ": " + header.getValue());
}public class ContentType {
// Constructors
public ContentType();
public ContentType(String s) throws ParseException;
public ContentType(String primaryType, String subType, ParameterList list);
// Type access
public String getPrimaryType();
public String getSubType();
// Parameter access
public String getParameter(String name);
public ParameterList getParameterList();
public void setParameter(String name, String value);
public void setParameterList(ParameterList list);
// Type operations
public String getBaseType();
public boolean match(ContentType cType);
public boolean match(String s);
public String toString();
}public class ContentDisposition {
// Constructors
public ContentDisposition();
public ContentDisposition(String disposition) throws ParseException;
public ContentDisposition(String disposition, ParameterList list);
// Disposition access
public String getDisposition();
public void setDisposition(String disposition);
// Parameter access
public String getParameter(String name);
public ParameterList getParameterList();
public void setParameter(String name, String value);
public void setParameterList(ParameterList list);
// String representation
public String toString();
}public class ParameterList {
// Constructors
public ParameterList();
public ParameterList(String s) throws ParseException;
// Parameter access
public int size();
public String get(String name);
public void set(String name, String value);
public void set(String name, String value, String charset);
public void remove(String name);
public Enumeration<String> getNames();
// String representation
public String toString();
public String toString(int used);
}import jakarta.mail.internet.*;
// Parse Content-Type
ContentType contentType = new ContentType("text/html; charset=utf-8; boundary=xyz123");
System.out.println("Primary type: " + contentType.getPrimaryType()); // "text"
System.out.println("Sub type: " + contentType.getSubType()); // "html"
System.out.println("Charset: " + contentType.getParameter("charset")); // "utf-8"
// Create new Content-Type
ContentType newType = new ContentType("application", "pdf", null);
newType.setParameter("name", "document.pdf");
// Parse Content-Disposition
ContentDisposition disposition = new ContentDisposition("attachment; filename=\"document.pdf\"");
System.out.println("Disposition: " + disposition.getDisposition()); // "attachment"
System.out.println("Filename: " + disposition.getParameter("filename")); // "document.pdf"
// Work with parameters
ParameterList params = new ParameterList();
params.set("charset", "utf-8");
params.set("boundary", "----=_NextPart_000_0001");
System.out.println("Parameters: " + params.toString());The MimeUtility class provides encoding/decoding utilities for MIME content.
public class MimeUtility {
// Text encoding/decoding
public static String encodeText(String text) throws UnsupportedEncodingException;
public static String encodeText(String text, String charset, String encoding) throws UnsupportedEncodingException;
public static String decodeText(String etext) throws UnsupportedEncodingException;
// Word encoding/decoding
public static String encodeWord(String word) throws UnsupportedEncodingException;
public static String encodeWord(String word, String charset, String encoding) throws UnsupportedEncodingException;
public static String decodeWord(String eword) throws ParseException, UnsupportedEncodingException;
// Stream encoding/decoding
public static InputStream encode(InputStream is, String encoding) throws MessagingException;
public static OutputStream encode(OutputStream os, String encoding) throws MessagingException;
public static InputStream decode(InputStream is, String encoding) throws MessagingException;
// Charset utilities
public static String getDefaultJavaCharset();
public static String getDefaultMIMECharset();
public static String mimeCharset(String charset);
public static String javaCharset(String charset);
// Quote utilities
public static String quote(String word, String specials);
public static String unfold(String s);
public static String fold(int used, String s);
}import jakarta.mail.internet.*;
// Encode non-ASCII text for headers
String encodedSubject = MimeUtility.encodeText("Héllo Wörld", "UTF-8", "B");
message.setSubject(encodedSubject);
// Decode encoded text
String decodedText = MimeUtility.decodeText("=?UTF-8?B?SMOpbGxvIFfDtnJsZA==?=");
// Encode filename for attachment
String encodedFilename = MimeUtility.encodeWord("résumé.pdf", "UTF-8", "Q");
bodyPart.setFileName(encodedFilename);
// Work with streams
InputStream encodedStream = MimeUtility.encode(inputStream, "base64");
InputStream decodedStream = MimeUtility.decode(encodedStream, "base64");
// Charset conversion
String mimeCharset = MimeUtility.mimeCharset("UTF-8");
String javaCharset = MimeUtility.javaCharset("iso-8859-1");
// Text folding for long headers
String longHeader = "This is a very long header value that needs to be folded";
String foldedHeader = MimeUtility.fold(12, longHeader);The MailDateFormat class provides RFC822-compliant date formatting.
public class MailDateFormat extends SimpleDateFormat {
// Constructors
public MailDateFormat();
// Date formatting (inherited from SimpleDateFormat)
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos);
public Date parse(String text, ParsePosition pos);
}import jakarta.mail.internet.MailDateFormat;
import java.util.Date;
// Format date for mail headers
MailDateFormat mailDateFormat = new MailDateFormat();
String formattedDate = mailDateFormat.format(new Date());
message.setHeader("Date", formattedDate);
// Parse mail date
Date parsedDate = mailDateFormat.parse("Mon, 01 Jan 2024 12:00:00 +0000");Install with Tessl CLI
npx tessl i tessl/maven-jakarta-mail--jakarta-mail-api