一、導入java發郵件pom依賴:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
二、java代碼:
/**
* 發送帶有附件的郵件
*
* @param acceptAccount 接受者郵箱
* @param title 標題
* @param content 發送內容
* @param annexFile 附件(爲null則不帶附件)
*/
public Future sendMailWithAnnex(final String acceptAccount, final String title, final String content, File annexFile) {
//線程池submit可以去掉,submit裏面纔是發郵件的代碼
return ThreadPoolUtil.getSingletonExecutor().submit(() -> {
try {
//1、連接郵件服務器的參數配置
Properties props = new Properties();
//設置用戶的認證方式
props.setProperty("mail.smtp.auth", "true");
//設置傳輸協議
props.setProperty("mail.transport.protocol", "smtp");
//設置發件人的SMTP服務器地址
props.setProperty("mail.smtp.host", emailAddress);
//使用JSSE的SSL socketfactory來取代默認的socketfactory
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// 只處理SSL的連接,對於非SSL的連接不做處理
props.put("mail.smtp.socketFactory.fallback", "false");
//設置端口
props.put("mail.smtp.port", 465);
props.put("mail.smtp.socketFactory.port", 465);
//2、創建定義整個應用程序所需的環境信息的 Session 對象
Session session = Session.getInstance(props);
//設置調試信息在控制檯打印出來
session.setDebug(false);
//3、創建郵件的實例對象
//創建一封郵件的實例對象
MimeMessage msg = new MimeMessage(session);
//設置發件人地址
msg.setFrom(new InternetAddress(emailAccount));
/**
* 設置收件人地址(可以增加多個收件人、抄送、密送),即下面這一行代碼書寫多行
* MimeMessage.RecipientType.TO:發送
* MimeMessage.RecipientType.CC:抄送
* MimeMessage.RecipientType.BCC:密送
*/
msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(acceptAccount));
//設置郵件主題
msg.setSubject(title, "UTF-8");
Multipart multipart = new MimeMultipart();
{
BodyPart part = new MimeBodyPart();
part.setContent(content, "text/html;charset=UTF-8");//設置郵件文本內容
multipart.addBodyPart(part);
}
if (annexFile != null && annexFile.exists()) {
BodyPart part = new MimeBodyPart();
// 根據文件名獲取數據源
FileDataSource dataSource = new FileDataSource(annexFile);
DataHandler dataHandler = new DataHandler(dataSource);
// 得到附件本身並至入BodyPart
part.setDataHandler(dataHandler);
// 得到文件名同樣至入BodyPart
part.setFileName(MimeUtility.encodeText(dataSource.getName()));
multipart.addBodyPart(part);
}
msg.setContent(multipart);
//設置郵件的發送時間,默認立即發送
msg.setSentDate(new Date());
//4、根據session對象獲取郵件傳輸對象Transport
Transport transport = session.getTransport();
//設置發件人的賬戶名和密碼
transport.connect(emailAccount, emailPassword);
//發送郵件,併發送到所有收件人地址,message.getAllRecipients() 獲取到的是在創建郵件對象時添加的所有收件人, 抄送人, 密送人
transport.sendMessage(msg, msg.getAllRecipients());
//如果只想發送給指定的人,可以如下寫法
//transport.sendMessage(msg, new Address[]{new InternetAddress("[email protected]")});
//5、關閉郵件連接
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
});
}
三、出現異常:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty:
你的jre環境缺少了一個文件。。我是在windows下運行沒有任何問題,把jar包放到linux下就出現這個異常了。
然後對比了下jdk/jre/lib/security/cacerts這個文件,發現我windows上的jdk這個文件有一百多kb,而linux下的這個文件只有32字節。
把windows下的一百多kb的文件複製到linux下替換掉32字節的,然後再運行上面的代碼就沒有問題了。
四、注意
發送郵件的附件是有文件大小限制的,不同郵件服務器是不一樣的,自己百度一下各大郵件運營商的限制。
超出限制了,一下提供幾個思路:
1、壓縮。把附件壓縮之後再發過去。如果附件內容有大量文本之類的,幾百兆大小可以被壓到十分之一大小,正常其實到這就沒問題了。幾百兆大小文件,數據量幾百萬條了。圖片視頻就另說,很難壓縮。
2、壓縮之後還是超出限制:
(1)如果是文本類的可分隔成多個文件的數據,不影響用戶打開的,那麼可以分隔成多份郵件發送。
(2)如果是大圖片、大視頻之類的,分隔之後無法正常使用,那麼這個就不能用(1)的方式,可以自己搭建個文件服務器,生成鏈接用郵件發送給用戶,用於通過鏈接去下載。
迫不得已再自己搭建文件服務器,因爲帶寬和服務器是要錢的。。如果公司願意給錢給服務器那自然好。