Topik ini menjelaskan cara mengirim email melalui Simple Mail Transfer Protocol (SMTP) menggunakan JavaMail API.
Tambahkan dependensi berikut ke file pom.xml Maven Anda:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
Parameter koneksi
Konfigurasikan nilai-nilai berikut sebelum menjalankan kode contoh:
|
Parameter |
Nilai |
Catatan |
|
SMTP server |
|
Titik akhir SMTP Direct Mail |
|
Port 80 atau 25 |
Tanpa enkripsi |
Bawaan. Gunakan jika port 465 diblokir. |
|
Port 465 |
SSL/TLS |
Memerlukan konfigurasi |
|
Username |
Alamat pengirim Anda |
Alamat pengirim yang dibuat di Konsol Direct Mail. |
|
Password |
Password SMTP |
Diatur saat membuat alamat pengirim di Konsol. |
Kode contoh
Jangan pernah menyematkan kredensial secara langsung di kode sumber atau melakukan commit ke sistem kontrol versi. Di lingkungan produksi, muat USER_NAME dan PASSWORD dari variabel lingkungan atau secrets manager.
Konten contoh berikut menggunakan JavaMail MimeMessage API untuk melakukan autentikasi dengan server SMTP Direct Mail, menyusun email berisi konten HTML, dan memanggil Transport.send(). Bagian yang dikomentari menunjukkan fitur opsional: teks biasa, lampiran, SSL, dan pelacakan email.
package org.example;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
//import java.net.MalformedURLException;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;
//import java.util.HashMap;
//import java.util.Base64;
//import java.net.URL;
//import java.io.IOException;
//import java.io.InputStream;
//import javax.mail.util.ByteArrayDataSource;
//import java.net.URLEncoder;
//import javax.activation.DataHandler;
//import javax.activation.FileDataSource;
//import javax.activation.URLDataSource;
//import com.google.gson.GsonBuilder;
public class SampleMail {
// Konfigurasikan konstanta
private static final String SMTP_HOST = "smtpdm.aliyun.com";
private static final int SMTP_PORT = 80;
private static final String USER_NAME = "Alamat Pengirim";
private static final String PASSWORD = "xxxxxxx";
protected static String genMessageID(String mailFrom) {
// Hasilkan Message-ID:
if (!mailFrom.contains("@")) {
throw new IllegalArgumentException("Format email tidak valid: " + mailFrom);
}
String domain = mailFrom.split("@")[1];
UUID uuid = UUID.randomUUID();
return "<" + uuid.toString() + "@" + domain + ">";
}
private static void setRecipients(MimeMessage message, Message.RecipientType type, String[] recipients)
throws MessagingException {
// Atur alamat penerima
if (recipients == null || recipients.length == 0) {
return; // Jangan atur jika daftar kosong
}
InternetAddress[] addresses = new InternetAddress[recipients.length];
for (int h = 0; h < recipients.length; h++) {
addresses[h] = new InternetAddress(recipients[h]);
}
message.setRecipients(type, addresses);
}
public static void main(String[] args) throws MessagingException, UnsupportedEncodingException {
// Konfigurasikan properti lingkungan untuk mengirim email
final Properties props = new Properties();
// Untuk mengirim email melalui SMTP, verifikasi identitas diperlukan
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", SMTP_HOST);
//Atur port:
props.put("mail.smtp.port", SMTP_PORT);// atau "25". Jika Anda menggunakan SSL, hapus konfigurasi untuk port 80 atau 25 dan gunakan konfigurasi berikut:
//Metode enkripsi:
//props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
//props.put("mail.smtp.socketFactory.fallback", "false");// Nonaktifkan fallback ke koneksi tanpa enkripsi
//props.put("mail.smtp.socketFactory.port", "465");
//props.put("mail.smtp.port", "465");
props.put("mail.smtp.from", USER_NAME); // Parameter mailfrom
props.put("mail.user", USER_NAME);// Akun pengirim (alamat pengirim yang dibuat di Konsol)
props.put("mail.password", PASSWORD);// Password SMTP untuk alamat pengirim (atur password untuk alamat pengirim di Konsol)
//props.put("mail.smtp.connectiontimeout", 1000);
System.setProperty("mail.mime.splitlongparameters", "false");// Ini mengatasi masalah tampilan yang disebabkan oleh nama lampiran terlalu panjang
//props.setProperty("mail.smtp.ssl.enable", "true"); // Gunakan ini dengan port 465
// Bangun informasi otorisasi untuk verifikasi identitas SMTP
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USER_NAME, PASSWORD);
}
};
//Buat sesi email menggunakan properti lingkungan dan informasi otorisasi
Session mailSession = Session.getInstance(props, authenticator);
String messageIDValue = genMessageID(USER_NAME);
MimeMessage message = new MimeMessage(mailSession) {
@Override
protected void updateMessageID() throws MessagingException {
setHeader("Message-ID", messageIDValue);
}
};
try {
// Atur alamat dan nama email pengirim. Gunakan alamat pengirim yang dikonfigurasi di Konsol. Harus sama dengan mail.user di atas. Anda dapat menyesuaikan nama.
InternetAddress from = new InternetAddress(USER_NAME, "Nama Panggilan Pengirim");// Parameter from. Dapat digunakan untuk meneruskan. Catatan: Email yang diteruskan lebih mungkin ditolak penerima atau masuk folder spam.
message.setFrom(from);
setRecipients(message, Message.RecipientType.TO, new String[]{"alamat_penerima_1", "alamat_penerima_2"});
setRecipients(message, Message.RecipientType.CC, new String[]{"alamat_penerima_3", "alamat_penerima_4"});
setRecipients(message, Message.RecipientType.BCC, new String[]{"alamat_penerima_5", "alamat_penerima_6"});
InternetAddress replyToAddress = new InternetAddress("alamat_balasan");
message.setReplyTo(new Address[]{replyToAddress});// Opsional. Atur alamat balasan.
message.setSentDate(new Date());
message.setSubject("Subjek Uji Coba");
// message.setContent("Konten TXT uji coba 1", "text/text;charset=UTF-8");// Konten teks biasa. Akan ditimpa jika Anda menggunakan MimeBodyPart.
// atau
// message.setContent("Uji coba<br> konten HTML 2", "text/html;charset=UTF-8");// Konten HTML. Akan ditimpa jika Anda menggunakan MimeBodyPart.
// // Untuk mengaktifkan layanan pelacakan email, gunakan kode berikut untuk mengatur header pelacakan. Untuk prasyarat dan batasan, lihat dokumen "Cara mengaktifkan fitur pelacakan data?".
// String tagName = "namatag4";
// HashMap<String, String> trace = new HashMap<>();
// // Ini adalah string "1"
// trace.put("OpenTrace", "1"); // Aktifkan pelacakan pembukaan email
// trace.put("LinkTrace", "1"); // Aktifkan pelacakan klik URL dalam email
// trace.put("TagName", tagName); // Nama tag yang dibuat di Konsol
// String jsonTrace = new GsonBuilder().setPrettyPrinting().create().toJson(trace);
// //System.out.println(jsonTrace);
// String base64Trace = new String(Base64.getEncoder().encode(jsonTrace.getBytes()));
// // Atur header pelacakan
// message.addHeader("X-AliDM-Trace", base64Trace);
// Contoh nilai dalam email asli (EML): X-AliDM-Trace: eyJUYWdOYW1lIjoiVGVzdCIsIk9wZW5UcmFjZSI6IjEiLCJMaW5rVHJhY2UiOiIxIn0=
// Kirim lampiran dan konten:
// Buat pesan multipart
Multipart multipart = new MimeMultipart();
// // Buat BodyPart untuk konten teks biasa
// BodyPart textPart = new MimeBodyPart();
// textPart.setText("Konten TXT uji coba 3");
// multipart.addBodyPart(textPart);
// Buat BodyPart untuk konten HTML
BodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent("Uji coba<br> konten HTML 4", "text/html;charset=UTF-8");// Atur konten email. Ini akan menimpa message.setContent sebelumnya.
multipart.addBodyPart(htmlPart);
// // Bagian lampiran
// // Kirim lampiran. Ukuran total email tidak boleh melebihi 15 MB. Buat bagian pesan.
// // Kirim lampiran lokal
// String[] fileList = {"C:\\Users\\Downloads\\test1.txt", "C:\\Users\\Downloads\\test2.txt"};
// for (String filePath : fileList) {
// MimeBodyPart mimeBodyPart = new MimeBodyPart();
//
// FileDataSource fileDataSource = new FileDataSource(filePath);
// mimeBodyPart.setDataHandler(new DataHandler(fileDataSource));
// // Ini menangani karakter teracak pada nama lampiran berbahasa Tionghoa (termasuk path file)
// mimeBodyPart.setFileName(MimeUtility.encodeWord(fileDataSource.getName()));
// mimeBodyPart.addHeader("Content-Transfer-Encoding", "base64");
// multipart.addBodyPart(mimeBodyPart);
// }
// // Kirim lampiran dari URL
// String[] fileListUrl = {"https://example.oss-cn-shanghai.aliyuncs.com/xxxxxxxxxxx1.png", "https://example.oss-cn-shanghai.aliyuncs.com/xxxxxxxxxxx2.png"};
// for (String fileUrl : fileListUrl) {
// URL url = new URL(fileUrl);
// String filename = url.getPath();
// filename = filename.substring(filename.lastIndexOf('/') + 1);
// try (InputStream in = url.openStream()) {
// // Buat bagian lampiran
// MimeBodyPart attachmentPart = new MimeBodyPart();
// // Gunakan sumber data berbasis byte array
// ByteArrayDataSource ds = new ByteArrayDataSource(in, "application/octet-stream");
// attachmentPart.setDataHandler(new javax.activation.DataHandler(ds));
// attachmentPart.setFileName(filename);
// attachmentPart.setDisposition(MimeBodyPart.ATTACHMENT);
// multipart.addBodyPart(attachmentPart);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// }
// Tambahkan pesan lengkap
message.setContent(multipart);
// Akhir kode untuk mengirim lampiran
//mailSession.setDebug(true);// Aktifkan mode debug
Transport.send(message);
System.out.println("Pengiriman selesai!");
} catch (MessagingException | UnsupportedEncodingException e) {
System.err.println("Gagal mengirim email: " + e.getMessage());
e.printStackTrace();
// } catch (MalformedURLException e) {
// throw new RuntimeException(e);
}
}
}
Header SMTP kustom
Gunakan header kustom berikut untuk mengaktifkan pelacakan dan penandaan email. Teruskan header ini sebagai JSON yang diencode Base64 melalui message.addHeader(). Untuk prasyarat dan langkah konfigurasi, lihat dokumentasi pelacakan email.
|
Header |
Kunci |
Nilai |
Deskripsi |
|
|
|
|
Melacak event pembukaan email. |
|
|
|
|
Melacak klik URL dalam isi email. |
|
|
|
Nama tag email Anda |
Mengaitkan pesan dengan tag email yang dibuat di Konsol. |
Blok pelacakan yang dikomentari dalam kode contoh membangun objek JSON dengan kunci-kunci tersebut, mengencode-nya dalam Base64, lalu mengaturnya sebagai header X-AliDM-Trace. Header EML yang dihasilkan tampak seperti:
X-AliDM-Trace: eyJUYWdOYW1lIjoiVGVzdCIsIk9wZW5UcmFjZSI6IjEiLCJMaW5rVHJhY2UiOiIxIn0=