package book.email;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
/**
* 邮件接收器,目前支持pop3协议。
* 能够接收文本、HTML和带有附件的邮件
*/
public class MailReceiver {
// 收邮件的参数配置
private MailReceiverInfo receiverInfo;
// 与邮件服务器连接后得到的邮箱
private Store store;
// 收件箱
private Folder folder;
// 收件箱中的邮件消息
private Message[] messages;
// 当前正在处理的邮件消息
private Message currentMessage;
private String currentEmailFileName;
public MailReceiver(MailReceiverInfo receiverInfo) {
this.receiverInfo = receiverInfo;
}
/**
* 收邮件
*/
public void receiveAllMail() throws Exception{
if (this.receiverInfo == null){
throw new Exception("必须提供接收邮件的参数!");
}
// 连接到服务器
if (this.connectToServer()) {
// 打开收件箱
if (this.openInBoxFolder()) {
// 获取所有邮件
this.getAllMail();
this.closeConnection();
} else {
throw new Exception("打开收件箱失败!");
}
} else {
throw new Exception("连接邮件服务器失败!");
}
}
/**
* 登陆邮件服务器
*/
private boolean connectToServer() {
// 判断是否需要身份认证
MyAuthenticator authenticator = null;
if (this.receiverInfo.isValidate()) {
// 如果需要身份认证,则创建一个密码验证器
authenticator = new MyAuthenticator(this.receiverInfo.getUserName(),
this.receiverInfo.getPassword());
}
//创建session
Session session = Session.getInstance(this.receiverInfo
.getProperties(), authenticator);
//创建store,建立连接
try {
this.store = session.getStore(this.receiverInfo.getProtocal());
} catch (NoSuchProviderException e) {
System.out.println("连接服务器失败!");
return false;
}
System.out.println("connecting");
try {
this.store.connect();
} catch (MessagingException e) {
System.out.println("连接服务器失败!");
return false;
}
System.out.println("连接服务器成功");
return true;
}
/**
* 打开收件箱
*/
private boolean openInBoxFolder() {
try {
this.folder = store.getFolder("INBOX");
// 只读
folder.open(Folder.READ_ONLY);
return true;
} catch (MessagingException e) {
System.err.println("打开收件箱失败!");
}
return false;
}
/**
* 断开与邮件服务器的连接
*/
private boolean closeConnection() {
try {
if (this.folder.isOpen()) {
this.folder.close(true);
}
this.store.close();
System.out.println("成功关闭与邮件服务器的连接!");
return true;
} catch (Exception e) {
System.out.println("关闭和邮件服务器之间连接时出错!");
}
return false;
}
/**
* 获取messages中的所有邮件
* @throws MessagingException
*/
private void getAllMail() throws MessagingException {
//从邮件文件夹获取邮件信息
this.messages = this.folder.getMessages();
System.out.println("总的邮件数目:" + messages.length);
System.out.println("新邮件数目:" + this.getNewMessageCount());
System.out.println("未读邮件数目:" + this.getUnreadMessageCount());
//将要下载的邮件的数量。
int mailArrayLength = this.getMessageCount();
System.out.println("一共有邮件" + mailArrayLength + "封");
int errorCounter = 0; //邮件下载出错计数器
int successCounter = 0;
for (int index = 0; index < mailArrayLength; index++) {
try {
this.currentMessage = (messages[index]); //设置当前message
System.out.println("正在获取第" + index + "封邮件......");
this.showMailBasicInfo();
getMail(); //获取当前message
System.out.println("成功获取第" + index + "封邮件");
successCounter++;
} catch (Throwable e) {
errorCounter++;
System.err.println("下载第" + index + "封邮件时出错");
}
}
System.out.println("------------------");
System.out.println("成功下载了" + successCounter + "封邮件");
System.out.println("失败下载了" + errorCounter + "封邮件");
System.out.println("------------------");
}
/**
* 显示邮件的基本信息
*/
private void showMailBasicInfo() throws Exception{
showMailBasicInfo(this.currentMessage);
}
private void showMailBasicInfo(Message message) throws Exception {
System.out.println("-------- 邮件ID:" + this.getMessageId()
+ " ---------");
System.out.println("From:" + this.getFrom());
System.out.println("To:" + this.getTOAddress());
System.out.println("CC:" + this.getCCAddress());
System.out.println("BCC:" + this.getBCCAddress());
System.out.println("Subject:" + this.getSubject());
System.out.println("发送时间::" + this.getSentDate());
System.out.println("是新邮件?" + this.isNew());
System.out.println("要求回执?" + this.getReplySign());
System.out.println("包含附件?" + this.isContainAttach());
System.out.println("------------------------------");
}
/**
* 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同
* "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
*/
private String getTOAddress() throws Exception {
return getMailAddress("TO", this.currentMessage);
}
private String getCCAddress() throws Exception {
return getMailAddress("CC", this.currentMessage);
}
private String getBCCAddress() throws Exception {
return getMailAddress("BCC", this.currentMessage);
}
/**
* 获得邮件地址
* @param type 类型,如收件人、抄送人、密送人
* @param mimeMessage 邮件消息
* @return
* @throws Exception
*/
private String getMailAddress(String type, Message mimeMessage)
throws Exception {
String mailaddr = "";
String addtype = type.toUpperCase();
InternetAddress[] address = null;
if (addtype.equals("TO") || addtype.equals("CC")
|| addtype.equals("BCC")) {
if (addtype.equals("TO")) {
address = (InternetAddress[]) mimeMessage
.getRecipients(Message.RecipientType.TO);
} else if (addtype.equals("CC")) {
address = (InternetAddress[]) mimeMessage
.getRecipients(Message.RecipientType.CC);
} else {
address = (InternetAddress[]) mimeMessage
.getRecipients(Message.RecipientType.BCC);
}
if (address != null) {
for (int i = 0; i < address.length; i++) {
// 先获取邮件地址
String email = address[i].getAddress();
if (email == null){
email = "";
}else {
email = MimeUtility.decodeText(email);
}
// 再取得个人描述信息
String personal = address[i].getPersonal();
if (personal == null){
personal = "";
} else {
personal = MimeUtility.decodeText(personal);
}
// 将个人描述信息与邮件地址连起来
String compositeto = personal + "<" + email + ">";
// 多个地址时,用逗号分开
mailaddr += "," + compositeto;
}
mailaddr = mailaddr.substring(1);
}
} else {
throw new Exception("错误的地址类型!!");
}
return mailaddr;
}
/**
* 获得发件人的地址和姓名
* @throws Exception
*/
private String getFrom() throws Exception {
return getFrom(this.currentMessage);
}
private String getFrom(Message mimeMessage) throws Exception {
InternetAddress[] address = (InternetAddress[]) mimeMessage.getFrom();
// 获得发件人的邮箱
String from = address[0].getAddress();
if (from == null){
from = "";
}
// 获得发件人的描述信息