JavaMail 是 Java 平台發送電子郵件的標準 API。本文提供兩個生產級封裝類:SendMail(輕量獨立版)與 EmailServer(Spring 整合、單例、模板支援),涵蓋純文本/HTML 郵件、多附件、多收件人、郵件伺服器配置管理等實戰需求。
javax.mail、javax.activation)。public class SendMail {
private static final String MAIL_REGEX = "^[\\w\\.=-]+@[\\w\\.-]+\\.[\\w]{2,3}$";
private String mailServer;
private String sender;
private String[] receiver;
// 多重配置入口
public void setMailBasicInfo(String mailServer, String sender, String receiver) { ... }
public void setMailBasicInfo(String mailServer, String sender, String[] users) { ... }
public void setMailBasicInfo(String mailServer, String sender, List<String> users) { ... }
// 統一發送入口
public boolean send(String subject, String content, List<String> fileNames) {
subject = subject == null ? "" : subject;
content = content == null ? "" : content;
Properties props = new Properties();
props.put("mail.smtp.host", mailServer);
Session session = Session.getInstance(props, null);
try {
InternetAddress[] to = getReceiverList();
if (to.length == 0) return false;
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(sender));
msg.setRecipients(Message.RecipientType.TO, to);
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
// 多部分容器:文本 + 附件
Multipart mp = new MimeMultipart();
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(content, "text/html;charset=UTF-8");
mp.addBodyPart(textPart);
// 處理附件
if (fileNames != null) {
for (String fn : fileNames) {
File f = new File(fn);
if (!f.isFile()) continue;
MimeBodyPart filePart = new MimeBodyPart();
FileDataSource fds = new FileDataSource(f);
filePart.setDataHandler(new DataHandler(fds));
filePart.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B"));
mp.addBodyPart(filePart);
}
}
msg.setContent(mp);
Transport.send(msg);
return true;
} catch (Exception e) {
log.error("郵件發送失敗", e);
return false;
}
}
// 重載簡化調用
public boolean send(String subject, String content) { return send(subject, content, null); }
public boolean send(String subject) { return send(subject, null); }
// 解析收件人列表
private InternetAddress[] getReceiverList() throws AddressException {
List<InternetAddress> list = new ArrayList<>();
for (String r : receiver) {
if (r.matches(MAIL_REGEX)) list.add(new InternetAddress(r));
}
return list.toArray(new InternetAddress[0]);
}
}
SendMail mail = new SendMail();
mail.setMailBasicInfo("smtp.163.com", "sender@163.com", Arrays.asList("a@qq.com", "b@gmail.com"));
String html = "<h1>測試郵件</h1><a href='https://example.com'>點擊鏈接</a>";
List<String> attachments = Arrays.asList("/path/report.pdf", "/path/image.png");
mail.send("測試主題", html, attachments);
EmailConfig)注入,自動根據發件人域名匹配 SMTP 設定。Authenticator,支援 SSL/TLS(需補全 SSL SocketFactory 配置)。sendTextMail / sendHtmlMail 語義清晰。@Component // Spring Bean
public class EmailServer {
private static final Logger log = LoggerFactory.getLogger(EmailServer.class);
@Autowired private List<EmailConfig> config; // 多郵箱配置
private boolean isDebug = false;
private boolean isAuth = true;
// 單例獲取
public static EmailServer getInstance() {
return ApplicationHelper.getInstance().getBean(EmailServer.class);
}
// 文本郵件
public boolean sendTextMail(String username, String password, String title,
String content, String receiver) { ... }
public boolean sendTextMail(String username, String password, String title,
String content, List<String> receivers) { ... }
// HTML 郵件
public boolean sendHtmlMail(String username, String password, String title,
String content, String receiver) { ... }
public boolean sendHtmlMail(String username, String password, String title,
String content, List<String> receivers) { ... }
// 核心構建 Message
private Message makeTextMail(Session session, String title, String content,
String from, List<String> receivers, boolean isHtml) {
MimeMessage msg = new MimeMessage(session);
msg.setSubject(title, "UTF-8");
if (isHtml) msg.setContent(content, "text/html;charset=UTF-8");
else msg.setText(content, "UTF-8");
msg.setFrom(new InternetAddress(from));
msg.setRecipients(Message.RecipientType.TO,
receivers.stream().filter(ValidateUtils::isEmail)
.map(InternetAddress::new).toArray(InternetAddress[]::new));
msg.setSentDate(new Date());
return msg;
}
// 根據發件人域名自動匹配 SMTP 配置
private EmailConfig getEmailConfig(String email) { ... }
}
<!-- applicationContext.xml -->
<bean class="com.message.base.email.EmailServer">
<property name="config">
<list>
<bean class="com.message.base.email.EmailConfig">
<property name="name" value="163" />
<property name="smtp" value="smtp.163.com" />
<property name="port" value="465" /> <!-- SSL 端口 -->
</bean>
<bean class="com.message.base.email.EmailConfig">
<property name="name" value="qq" />
<property name="smtp" value="smtp.qq.com" />
<property name="port" value="587" /> <!-- TLS 端口 -->
</bean>
</list>
</property>
<property name="isAuth" value="true" />
<property name="isDebug" value="false" />
</bean>
@Autowired EmailServer emailServer; // 或 EmailServer.getInstance()
List<String> to = Arrays.asList("user1@163.com", "user2@qq.com");
emailServer.sendHtmlMail("admin@163.com", "password", "HTML 郵件測試",
"<span style='color:red'>內容</span><a href='https://baidu.com'>鏈接</a>", to);
emailServer.sendTextMail("admin@163.com", "password", "文本郵件測試", "純文本內容", to);
props.put("mail.smtp.ssl.enable", "true") (SSL) 或 props.put("mail.smtp.starttls.enable", "true") (TLS),並配置對應端口(465/587)。Transport.connect() 保持長連接,或引入 Spring Boot Mail 自動配置的連接池。@Async 或線程池提交,避免阻塞業務線程。MimeUtility.encodeText 避免中文亂碼。SendMail 適合無框架、輕量級專案快速接入;EmailServer 適合 Spring 生態企業級應用,提供配置管理、多賬號隔離、擴展性更強。兩者核心均基於 JavaMail MimeMessage + Multipart 實現多部分郵件構建。掌握郵件協議(SMTP/SSL/TLS)、MIME 結構、異步化與監控,才能構建可靠的通知觸達體系。