JavaMail是Sun發佈的處理電子郵件的應用程序接口,它預置了一些最常用的郵件傳送協議的實現方法,並且提供了很容易的方法去調用它們。JavaMail是Sun發佈的應用程序接口,所以目前它還沒有被JDK包含。因此你需要從Sun的官方網站上下載到JavaMail類文件包。除此之外還需要Sun的JAF(JavaBeans Activation Framework ),否則JavaMail將不能運行。
核心JavaMail API 由七個類組成:Session 、Message 、Address 、Authenticator 、Transport 、Store 及 Folder ,它們都來自javax.mail 、即JavaMail API 頂級包。可以用這些類完成大量常見的電子郵件任務,包括髮送消息、檢索消息、刪除消息、認證、回覆消息、轉發消息、管理附件、處理基於HTML文件格式的消息以及搜索或過濾郵件列表。有關JavaMail 的更多信息,請參考JavaMail 指南。
JavaMail的基礎知識
使用JavaMail是發送電子郵件所需要的組件 。
JavaMail的機構使處理電子郵件非常容易。下面列出了一些我們需要的類:
1.Properties
JavaMail需要Properties來創建一個session對象。它將尋找字符串"mail.smtp.host",屬性值就是發送郵件的主機,如:
Properties props = new Properties ();
props.put("mail.smtp.host", "smtp.sina.com"); // 可以換上你的smtp主機名。
props.put("mail.smtp.auth", "true"); // 身份驗證,目前免費郵件服務器都需要這一項
2.Session
這個Session類代表JavaMail中的一個郵件會話。每一個基於JavaMail的應用程序至少有一個Session(可以有任意多的Session)。在這個例子中,Session對象需要知道用來處理郵件的SMTP服務器。爲了做到這一點,你可以參照下面的例子用Properties 來創建一個Session 對象
Session session = Session.getDefaultInstance(props, null);
3.Transport
郵件是既可以被髮送也可以被受到。JavaMail使用了兩個不同的類來完成這兩個功能:Transport 和 Store。 Transport 是用來發送信息的,而Store用來收信。對於這的教程我們只需要用到Transport對象。Store的用法請參看Sun的JavaMail文檔。
用法:Transport transport = session.getTransport("smtp");
用JavaMail Session對象的getTransport 方法來初始化Transport。傳過去的字符串申明瞭對象所要使用的協議,如"smtp"。這將爲我們省了很多時間。因爲JavaMail已經內置了很多協議的實現方法。
注意: JavaMail並不是絕對支持每一個協議,目前支持IMAP、 SMTP和 POP3。
4.Message
Message對象將存儲我們實際發送的電子郵件信息,Message對象被作爲一個MimeMessage對象來創建並且需要知道應當選擇哪一個JavaMail session。
使用方法是:Message message = new MimeMessage(session);
郵件亂碼問題:
JavaMail中的郵件主題需要進行BASE64編碼,格式形如:=?GBK?B?xPq1xMPcwuvS0b6t1tjWw6Osx+u+ob/stcfCvKOssqLQ3rjEw9zC66Oh?=
所以,直接使用message.setSubject("中文主題"),或者message.setSubject("中文主題".getBytes ("ISO-8859-1"), "GBK"))都一樣會出現亂碼。在設置郵件主題前需要將主題字串的字節編碼爲BASE64格式,並添加編碼頭,示例代碼如下:
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
msg.setSubject("=?GBK?B?"+enc.encode(subject.getBytes())+"?=");
郵件發送源碼:
SendMail.java
package com.lzw.mail;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import com.lzw.io.Out;
/**
* 郵件發送程序
* @author 李趙偉 Create: 2007-12-19
*/
public class SendMail {
private Session session; //會話
private Transport transport; //發送郵件
private User user; //郵件相關的帳戶信息
private MailAddress mailAddress; //收件人地址
private MailBody mailBody; //郵件內容
private final String MAIL_SMTP_HOST = "mail.smtp.host";
private final String MAIL_SMTP_AUTH = "mail.smtp.auth";
public SendMail(User user) {
this.user = user;
init();
}
/**
* 初始化<code> Session, Transport </code>
*/
private void init() {
Authenticator auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user.getUsername(), user
.getPassword());
}
};
Properties props = new Properties();
// 設置發送郵件的郵件服務器的屬性(這裏使用網易的smtp服務器)
props.put(MAIL_SMTP_HOST, user.getHost());
// 需要經過授權,也就是有戶名和密碼的校驗,這樣才能通過驗證(一定要有這一條)
props.put(MAIL_SMTP_AUTH, "true");
// 用剛剛設置好的props對象構建一個session
session = Session.getDefaultInstance(props, auth);
try {
// 發送郵件
transport = session.getTransport("smtp");
// 連接服務器的郵箱
transport.connect(user.getHost(), user.getUsername(), user
.getPassword());
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
Out.pln("與 " + user.getHost() + " 成功建立會話");
}
/**
* 設置收件人地址
*
* @param mailAddress
*/
public void setAddress(MailAddress mailAddress) {
this.mailAddress = mailAddress;
}
/**
* 設置郵件內容
*
* @param mailBody
*/
public void setMailBody(MailBody mailBody) {
this.mailBody = mailBody;
}
/**
* 構造郵件的內容
*
* @return
* @throws AddressException
* @throws MessagingException
*/
private Message createMessage() throws AddressException, MessagingException {
// 用session爲參數定義消息對象
MimeMessage message = new MimeMessage(session);
// 加載發件人地址
message.setFrom(new InternetAddress(user.getFrom()));
message.setSentDate(new Date());
// 加載收件人地址
message.addRecipients(Message.RecipientType.TO, getAddress(mailAddress
.getTo()));
if (mailAddress.isHasCC())
message.addRecipients(Message.RecipientType.CC,
getAddress(mailAddress.getCc()));
// 加載標題
message.setSubject(mailBody.getSubject());
if (mailBody.isContentFlag() || mailBody.isAffixFlag()) {
// 向multipart對象中添加郵件的各個部分內容,包括文本內容和附件
Multipart multipart = new MimeMultipart();
if (mailBody.isContentFlag()) {
// 設置郵件的文本內容
MimeBodyPart contentPart = new MimeBodyPart();
if (mailBody.isMimeContent())
contentPart.setContent(mailBody.getContent(),
"text/html;charset=GBK");
else
contentPart.setText(mailBody.getContent());
multipart.addBodyPart(contentPart);
}
if (mailBody.isAffixFlag()) {
// 添加附件
BodyPart affixBody = new MimeBodyPart();
DataSource source = new FileDataSource(mailBody.getAffix());
// 添加附件的內容
affixBody.setDataHandler(new DataHandler(source));
// 添加附件的標題這裏很重要,通過下面的Base64編碼的轉換可以保證你的
// 中文附件標題名在發送時不會變成亂碼
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
String fileName = "=?GBK?B?"
+ enc.encode(mailBody.getAffixName().getBytes()) + "?=";
affixBody.setFileName(fileName);
multipart.addBodyPart(affixBody);
}
// 將multipart對象放到message中
message.setContent(multipart);
}
// 保存郵件
message.saveChanges();
return message;
}
/**
* 發送郵件,包含:郵件正文、(1個附件)
*
* @param debug
* 調試設置
*/
public void send(boolean debug) {
// 有了這句便可以在發送郵件的過程中在console處顯示過程信息,供調試使
// 用(你可以在控制檯(console)上看到發送郵件的過程)
session.setDebug(debug);
try {
Message message = createMessage();
transport.sendMessage(message, message.getAllRecipients());
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
Out.pln("\n----------------------------------------------------------");
Out.pln("- 郵件成功發送!");
Out.pln("- TO : " + Arrays.toString(mailAddress.getTo()));
if (mailAddress.isHasCC())
Out.pln("- CC : " + Arrays.toString(mailAddress.getCc()));
Out.pln("----------------------------------------------------------\n");
}
/**
* 關閉資源
*
* @throws MessagingException
*/
public void close() throws MessagingException {
if (null != transport)
transport.close();
}
public Address[] getAddress(String[] address) throws AddressException {
Address[] addrs = new InternetAddress[address.length];
for (int i = 0; i < address.length; i++)
addrs[i] = new InternetAddress(address[i]);
return addrs;
}
/**
* 測試
*/
public static void main(String[] args) {
String host = "smtp.sina.com";
String username = "";
String password = "";
// String from = "";
String to = "";
// String cc = null;
String subject = "測試";
String content = "<a href=http://www.baidu.com>baidu</a>";
boolean mimeContent = true;
String affix = "d:/temp/temp.txt";
String affixName = "temp.txt";
boolean debug = false;
// String userFile = "user.properties";
// String addressFile = "mailaddress.properties";
SendMail mail = null;
try {
try {
User user = new User(host, username, password);
MailAddress mailAddress = new MailAddress(to);
// User user = new User(userFile);
// MailAddress mailAddress = new MailAddress(SendMail.class
// .getResourceAsStream(addressFile));
MailBody mailBody = new MailBody(subject, content, mimeContent,
affix, affixName);
mail = new SendMail(user);
// for (int i = 0; i < 5; i++) {
// 設置發件人地址、收件人地址和郵件標題
mail.setAddress(mailAddress);
// 設置要發送附件的位置和標題
mail.setMailBody(mailBody);
// 設置smtp服務器以及郵箱的帳號和密碼
mail.send(debug);
// try {
// Thread.sleep(1 * 1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// mailBody = new MailBody(subject + "_" + (i + 1), content);
// }
} finally {
if (null != mail)
mail.close();
}
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
}
}
}
使用JavaMail發送郵件需要注意的地方:
使用免費的郵件服務器發送郵件時,需要對用戶的身份做驗證;而進行身份驗證的過程又比較消耗時間,當用戶需要發送多封郵件時如果每次都做身份驗證的話時間的消耗是非常大的;
在整個郵件發送過程中Session(會話)的建立只需要一次,也就是說身份驗證也只做一次就可以了,即Session session = Session. getDefaultInstance(props, auth);
發送郵件的過程相對比較簡單,有一個需要注意的地方就是連接郵件服務器時transport.connect(user.getHost(), user.getUsername(), user.getPassword());也只需要執行一次即可,這個過程和身份驗證一樣都需要消耗大量時間。
該程序只允許發送帶有一個附件的郵件
轉自:http://blog.163.com/fly_sky_java/blog/static/14042223420105763240769/