Java中處理郵件附件的方法(本地文件和在線URL)
發(fā)送帶附件的郵件是一個(gè)常見的需求。但在實(shí)際應(yīng)用中,附件的來源可能不同:
- 本地文件:直接從服務(wù)器的文件系統(tǒng)讀取
- 在線 URL:附件是一個(gè) HTTP 資源,需要先下載
如果郵件服務(wù)方法只支持 File 類型的附件,而數(shù)據(jù)來源是一個(gè) URL 鏈接,就需要進(jìn)行額外的處理
| 方案 | 適用場(chǎng)景 | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|---|
| 方案 1:下載文件后發(fā)送 | sendMultiMail 只能接受 File | -兼容所有 File 處理方法,確保附件可用 | -需要臨時(shí)存儲(chǔ),占用磁盤空間 |
| 方案 2:修改 sendMultiMail 使其支持 URL | sendMultiMail 支持 URL 附件 | - 無需存儲(chǔ)文件,減少 IO | - 需要改造 sendMultiMail,并且 URL 可能會(huì)失效 |
從實(shí)戰(zhàn)中學(xué)習(xí)出發(fā):

1. 本地文件
附件文件是 本地文件,可以直接使用 File 對(duì)象傳遞給郵件發(fā)送方法,例如:
List<File> attachments = Collections.singletonList(new File("C:\\images\\test.jpg"));
傳入 sendMultiMail 方法:
Long messageId = mailSendService.sendMultiMail(
mailList, getLoginUserId(), UserTypeEnum.ADMIN.getValue(),
templateCode, templateParams, attachments);
2. 在線URL
new File(String path) 只能處理 本地文件路徑,但如果xxx返回的是 HTTP URL(如 http://example.com/image.jpg),則會(huì)報(bào) FileNotFoundException,因?yàn)?Java 認(rèn)為這是一個(gè)無效的路徑
解決方法:
- 方案 1:先下載 URL 文件到本地,再作為 File 傳入
優(yōu)點(diǎn): ? 兼容所有支持 File 類型的郵件方法。? 確保文件下載完成后再發(fā)送,避免資源問題。
缺點(diǎn): ? 可能會(huì)導(dǎo)致 磁盤 IO 開銷,尤其是多個(gè)郵件附件時(shí)。? 需要臨時(shí)存儲(chǔ)文件,增加服務(wù)器磁盤負(fù)擔(dān)。 - 方案 2:修改 sendMultiMail 方法,讓它支持直接使用 URL
優(yōu)點(diǎn):? 避免本地存儲(chǔ),直接使用在線資源。? 減少 IO 開銷,更適合大規(guī)模郵件發(fā)送。
缺點(diǎn): ? 需要 sendMultiMail 方法支持 URL 附件,否則無法直接使用。? URL 可能會(huì)過期,影響郵件內(nèi)容長(zhǎng)期有效性。
可以使用 java.net.URL 和 Files.copy 方法下載文件:
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
public class FileDownloadUtil {
public static File downloadFileFromUrl(String fileUrl) throws IOException {
URL url = new URL(fileUrl); // 創(chuàng)建 URL 對(duì)象
File tempFile = File.createTempFile("attachment_", ".jpg"); // 生成臨時(shí)文件
try (InputStream in = url.openStream()) {
Files.copy(in, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
return tempFile;
}
}
下載后發(fā)送郵件
在發(fā)送郵件時(shí),先下載附件:
// 處理附件,將 HTTP 圖片下載到本地
List<File> attachments = new ArrayList<>();
try {
File downloadedFile = FileDownloadUtil.downloadFileFromUrl(cabinetSwapDO.getImgCntrF());
attachments.add(downloadedFile);
} catch (IOException e) {
e.printStackTrace(); // 記錄日志
}
// 發(fā)送郵件
Long xx = mailSendService.sendMultiMail(mail, getLoginUserId(), UserTypeEnum.ADMIN.getValue(),
templateCode, templateParams, attachments);
sendMultiMail 方法內(nèi)部使用的是 javax.mail,可以改造 sendMultiMail 以支持 URL:
import javax.activation.DataHandler;
import javax.activation.URLDataSource;
import javax.mail.internet.MimeBodyPart;
import java.net.URL;
public class MailAttachmentUtil {
public static MimeBodyPart createUrlAttachment(String fileUrl) throws Exception {
MimeBodyPart attachmentPart = new MimeBodyPart();
URL url = new URL(fileUrl);
attachmentPart.setDataHandler(new DataHandler(new URLDataSource(url)));
attachmentPart.setFileName("attachment.jpg"); // 可根據(jù)實(shí)際情況動(dòng)態(tài)命名
return attachmentPart;
}
}
3. 彩蛋
臨時(shí)下載的文件
Windows:通常存儲(chǔ)在 C:\Users\用戶名\AppData\Local\Temp
Linux / macOS:通常存儲(chǔ)在 /tmp/
截圖如下:

不希望存儲(chǔ)在系統(tǒng)臨時(shí)目錄,而是放到自定義目錄,可以這樣修改 downloadFileFromUrl 方法:
public static File downloadFileFromUrl(String fileUrl, String saveDir) throws IOException {
URL url = new URL(fileUrl);
// 確保目錄存在
File directory = new File(saveDir);
if (!directory.exists()) {
directory.mkdirs();
}
// 指定下載文件路徑
File file = new File(saveDir + File.separator + "attachment.jpg");
// 下載文件
try (InputStream in = url.openStream()) {
Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
return file;
}
調(diào)用方式:
File file = downloadFileFromUrl("http://example.com/image.jpg", "D:\\attachments");
System.out.println("Saved file path: " + file.getAbsolutePath());
到此這篇關(guān)于Java中處理郵件附件的方法(本地文件和在線URL)的文章就介紹到這了,更多相關(guān)Java處理郵件附件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot如何配置Scheduler定時(shí)器
這篇文章主要介紹了Springboot如何配置Scheduler定時(shí)器問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
JavaSE實(shí)戰(zhàn)之酒店訂房系統(tǒng)的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何利用JavaSE實(shí)現(xiàn)酒店訂房系統(tǒng),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaSE開發(fā)有一定的幫助,需要的可以參考一下2022-07-07
關(guān)于jpa中無法刪除onetomany中many問題的解決
這篇文章主要介紹了關(guān)于jpa中無法刪除onetomany中many問題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java IO創(chuàng)建目錄和文件實(shí)例代碼
本篇文章給大家分享了Java IO創(chuàng)建目錄和文件的實(shí)例代碼,過程很簡(jiǎn)單,大家可以測(cè)試參考下。2018-02-02
淺談controller中調(diào)用多個(gè)service方法的問題
這篇文章主要介紹了淺談controller中調(diào)用多個(gè)service方法的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
JAVA線程sleep()和wait()詳解及實(shí)例
這篇文章主要介紹了JAVA線程sleep()和wait()詳解及實(shí)例的相關(guān)資料,探討一下sleep()和wait()方法的區(qū)別和實(shí)現(xiàn)機(jī)制,需要的朋友可以參考下2017-05-05
Java在制作jar包時(shí)引用第三方j(luò)ar包的方法
這篇文章主要介紹了Java在制作jar包時(shí)引用第三方j(luò)ar包的方法的相關(guān)資料,需要的朋友可以參考下2016-01-01
SpringAMQP消息隊(duì)列(SpringBoot集成RabbitMQ方式)
這篇文章主要介紹了SpringAMQP消息隊(duì)列(SpringBoot集成RabbitMQ方式),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04

