使用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)的方法,添加附件到郵件體中,既未生成臨時文件,而且速度還極快。