javamail發送帶附件的郵件,發件速度快

     使用javamail發送郵件,準備工作

1.如果使用的是qq郵箱,則需要登錄QQ郵箱,找到“設置--賬戶”找到如下圖,將POP3/SMTP服務和IMAP/SMTP服務開啓,然後生成授權碼,這裏的授權碼,就是你要用來發郵件時,自己QQ郵箱的密碼(注意:QQ郵箱用javamail發郵件,用的是授權碼,而不是QQ郵箱的密碼)

2.如果使用的是163郵箱,則需要登錄163郵箱,找到“設置--POP3/SMTP/IMAP”,將其勾選上。對於163郵箱,有的郵箱能用163郵箱號和密碼就能發郵件,但是有的163郵箱就必須得使用授權碼,這個是因郵箱而異吧。。。我的163郵箱就得用授權碼才能通過javamail發郵件,但是我一個朋友的郵箱用登錄密碼就可以通過javamail發郵件

我寫的demo裏,附件是由前端先上傳到文件服務器(文件服務器以下簡稱“OSS”),然後前端將附件的信息(包含存儲在OSS上的地址)再傳給我,然後我再把附件添加到郵件體裏。代碼如下:

發件工具類:

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.URLDataSource;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import com.xhl.leads.leadsmail.sendmail.entity.MailAttachment;

public class SendMailUtil {
	public static void sendMail() throws Exception {
		int draft = 0;//默認不是草稿
		int priority = 3;//默認是普通郵件  優先級(1:緊急 3:普通 5:低)
		int receiptFlag = 0;//是否需要回執  默認是0,不需要回執
		String host = "smtp.163.com";
		Properties props = new Properties();
		props.setProperty("mail.transport.protocol", "smtp");// "smtp"
		props.setProperty("mail.smtp.host", host);// smtp.qq.com
		props.setProperty("mail.smtp.port", "465");// 465
		props.setProperty("mail.smtp.auth", "true");// "true"
//	    props.setProperty("mail.debug", "true");// "true"  註釋掉後,控制檯將不會再打印發送郵件主題內容的日誌
		props.setProperty("mail.smtp.socketFactory.class",     
                         "javax.net.ssl.SSLSocketFactory"); 
		props.setProperty("mail.smtp.socketFactory.fallback", "false"); 
		System.setProperty("mail.mime.splitlongparameters", "false");//設置了附件名過長問題,從而導致附件名顯示帶bin的錯誤,造成附件異常
		Session session = Session.getDefaultInstance(props);
		String from = "****@163.com";//發件人郵箱
		String passWord = "*****";
		String content = "您好:郵件!!!";
		Message message = new MimeMessage(session);
		message.setSentDate(new Date());
		// 設置發件人地址
		message.setFrom(new InternetAddress(from));
		// 設置主題
		message.setSubject("這是一封郵件");
		// 設置收件人
		message.addRecipients(Message.RecipientType.TO, 
        InternetAddress.parse(MimeUtility.encodeText("*****@qq.com")));
		// 設置抄送人
		message.addRecipients(Message.RecipientType.CC, 
        InternetAddress.parse(MimeUtility.encodeText("")));//選填
		// 設置密送人
		message.addRecipients(Message.RecipientType.BCC, 
        InternetAddress.parse(MimeUtility.encodeText("")));//選填
		if (draft == 1) { // 如果是草稿
			message.setFlag(Flags.Flag.DRAFT, true);
		}
		// 設置優先級(1:緊急 3:普通 5:低)
		if (priority == 1)
			message.setHeader("X-Priority", "1");
		// 如果receiptFlag=1 代表需要回執
		if (receiptFlag == 1)
			message.setHeader("Disposition-Notification-To", from);
		// 設置郵件內容
		Multipart multipart = new MimeMultipart();
		MimeBodyPart txtPart = new MimeBodyPart();
		txtPart.setContent(content, "text/html;charset=utf-8");
		multipart.addBodyPart(txtPart);
		
		List<MailAttachment> mailAttachmentList = new ArrayList<MailAttachment>(); //獲取當前郵件附件集合
		String attachmentUrl = "";
		String fileName = "";
		if (mailAttachmentList != null && mailAttachmentList.size() > 0) {
			for (MailAttachment attachment : mailAttachmentList) {
				attachmentUrl = attachment.getFilePath();
				fileName = attachment.getFileName();
				MimeBodyPart part = new MimeBodyPart();
				URL url = new URL(attachmentUrl);
	            DataSource dataSource=new URLDataSource(url);
				part.setDataHandler(new DataHandler(dataSource));
				part.setFileName(MimeUtility.encodeText(fileName));
				multipart.addBodyPart(part);
			}
		}
		message.setContent(multipart);
		message.setFlag(Flags.Flag.RECENT, true);
		message.saveChanges();
		if (draft == 0) {
			Transport transport = session.getTransport("smtp");
			transport.connect(host, from, passWord);
			transport.sendMessage(message, message.getAllRecipients());
			transport.close();
		}
	}
	public static void main(String[] args) {
		
		try {
			sendMail();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

附件對象:

import lombok.Data;

@Data
public class MailAttachment {
	private int id;
	private String filePath;//附件在文件服務器上的路徑
	private String fileName;//附件的名字
	private String fileSize;//附件的大小
	private int fileOrder;//附件的順序
	private String fileType;//附件類型
}

網上的很多javamail發送郵件,在將附件添加到郵件體時,都是用的File文件的形式,但是經過實踐,我發現用這種方式去將附件保存到郵件體中,對於我們這種先將附件存儲在OOS上,然後再從OSS上取下附件,速度很慢;找了很多資料,終於找到了以url的形式將附件添加到郵件體中

1)網上最常用的保存附件到郵件體中的方法:以File的方式

FileDataSource fds = new FileDataSource(file); // 得到數據源  
part.setDataHandler(new DataHandler(fds)); // 得到附件本身並至入BodyPart  將附件以文件的形式添加到javamail中

利用這種方法,我先將存儲到文件服務器上的文件得到,然後在本地生成臨時文件,將文件添加到郵件體中,待郵件發送成功後,將臨時文件在刪除,我發現速度很慢,尤其是附件好幾兆的時候,發一封郵件都得用時六七分鐘;

2)第二種保存附件到郵件體中的方法:以流的方式

DataSource dataSource= new ByteArrayDataSource(inputStream,"application/octet-stream");//將附件改爲以流的形式添加到javamail中
part.setDataHandler(new DataHandler(dataSource));

針對1)的現象,我想是不是我可以不生成臨時文件,而只是把附件從OSS上拿到這個文件的流,然後將流保存到郵件體中,發現這種方法會減少時間,但是也沒有減少很多

3)第三種保存附件到郵件體中的方法:以url的方式-----最佳方案

URL url = new URL(attachmentUrl);
DataSource dataSource=new URLDataSource(url);
part.setDataHandler(new DataHandler(dataSource));

使用3)的方法,添加附件到郵件體中,既未生成臨時文件,而且速度還極快。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章