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.Authenticator;
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.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.util.Properties;
/**
* 邮件接收器,目前支持pop3协议。 能够接收文本、HTML和带有附件的邮件
*
* 需要导入mail.jar
*/
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) {
}
// 连接到服务器
if (this.connectToServer()) {
// 打开收件箱
if (this.openInBoxFolder()) {
// 获取所有邮件
this.getAllMail();
this.closeConnection();
} else {
}
} else {
}
}
/**
* 登陆邮件服务器
*/
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());
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;
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++;
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"---密送人地址
*/
return getMailAddress("TO", this.currentMessage);
}
return getMailAddress("CC", this.currentMessage);
}
return getMailAddress("BCC", this.currentMessage);
}
/**
* 获得邮件地址
*
* @param type
* 类型,如收件人、抄送人、密送人
* @param mimeMessage
* 邮件消息
* @return
* @throws Exception
*/
private String getMailAddress
(String type, Message mimeMessage
)
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 {
}
return mailaddr;
}
/**
* 获得发件人的地址和姓名
*
* @throws Exception
*/
return getFrom(this.currentMessage);
}
InternetAddress[] address = (InternetAddress[]) mimeMessage.getFrom();
// 获得发件人的邮箱
String from
= address
[0].
getAddress();
if (from == null) {
from = "";
}
// 获得发件人的描述信息
String personal
= address
[0].
getPersonal();
if (personal == null) {
personal = "";
}
// 拼成发件人完整信息
String fromaddr
= personal
+ "<" + from
+ ">";
return fromaddr;
}
/**
* 获取messages中message的数量
*
* @return
*/
private int getMessageCount() {
return this.messages.length;
}
/**
* 获得收件箱中新邮件的数量
*
* @return
* @throws MessagingException
*/
private int getNewMessageCount() throws MessagingException {
return this.folder.getNewMessageCount();
}
/**
* 获得收件箱中未读邮件的数量
*
* @return
* @throws MessagingException
*/
private int getUnreadMessageCount() throws MessagingException {
return this.folder.getUnreadMessageCount();
}
/**
* 获得邮件主题
*/
private String getSubject
() throws MessagingException
{
return getSubject(this.currentMessage);
}
private String getSubject
(Message mimeMessage
) throws MessagingException
{
try {
// 将邮件主题解码
subject = MimeUtility.decodeText(mimeMessage.getSubject());
if (subject == null) {
subject = "";
}
}
return subject;
}
/**
* 获得邮件发送日期
*/
return getSentDate(this.currentMessage);
}
return mimeMessage.getSentDate();
}
/**
* 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false"
*/
private boolean getReplySign() throws MessagingException {
return getReplySign(this.currentMessage);
}
private boolean getReplySign(Message mimeMessage) throws MessagingException {
boolean replysign = false;
String needreply
[] = mimeMessage
.getHeader("Disposition-Notification-To");
if (needreply != null) {
replysign = true;
}
return replysign;
}
/**
* 获得此邮件的Message-ID
*/
private String getMessageId
() throws MessagingException
{
return getMessageId(this.currentMessage);
}
private String getMessageId
(Message mimeMessage
) throws MessagingException
{
return ((MimeMessage) mimeMessage).getMessageID();
}
/**
* 判断此邮件是否已读,如果未读返回返回false,反之返回true
*/
private boolean isNew() throws MessagingException {
return isNew(this.currentMessage);
}
private boolean isNew(Message mimeMessage) throws MessagingException {
boolean isnew = false;
Flags flags = mimeMessage.getFlags();
Flags.Flag[] flag = flags.getSystemFlags();
for (int i = 0; i < flag.length; i++) {
if (flag[i] == Flags.Flag.SEEN) {
isnew = true;
break;
}
}
return isnew;
}
/**
* 判断此邮件是否包含附件
*/
private boolean isContainAttach
() throws Exception {
return isContainAttach(this.currentMessage);
}
private boolean isContainAttach
(Part part
) throws Exception {
boolean attachflag = false;
if (part.isMimeType("multipart/*")) {
// 如果邮件体包含多部分
Multipart mp = (Multipart) part.getContent();
// 遍历每部分
for (int i = 0; i < mp.getCount(); i++) {
// 获得每部分的主体
BodyPart bodyPart = mp.getBodyPart(i);
String disposition
= bodyPart.
getDisposition();
if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
.equals(Part.INLINE)))) {
attachflag = true;
} else if (bodyPart.isMimeType("multipart/*")) {
attachflag = isContainAttach((Part) bodyPart);
} else {
String contype
= bodyPart.
getContentType();
if (contype.toLowerCase().indexOf("application") != -1) {
attachflag = true;
}
if (contype.toLowerCase().indexOf("name") != -1) {
attachflag = true;
}
}
}
} else if (part.isMimeType("message/rfc822")) {
attachflag = isContainAttach((Part) part.getContent());
}
return attachflag;
}
/**
* 获得当前邮件
*/
try {
this.saveMessageAsFile(currentMessage);
this.parseMessage(currentMessage);
} catch (MessagingException e) {
throw new MessagingException("邮件转换出错");
e.printStackTrace();
}
}
/**
* 保存邮件源文件
*/
private void saveMessageAsFile(Message message) {
try {
// 将邮件的ID中尖括号中的部分做为邮件的文件名
String oriFileName
= getInfoBetweenBrackets
(this.
getMessageId(
message).toString());
// 设置文件后缀名。若是附件则设法取得其文件后缀名作为将要保存文件的后缀名,
// 若是正文部分则用.htm做后缀名
String fileNameWidthExtension
= this.
receiverInfo.
getEmailDir()
+ oriFileName + this.receiverInfo.getEmailFileSuffix();
File storeFile
= new File(fileNameWidthExtension
);
for (int i = 0; storeFile.exists(); i++) {
emlName = oriFileName + i;
fileNameWidthExtension = this.receiverInfo.getEmailDir()
+ emlName + this.receiverInfo.getEmailFileSuffix();
storeFile
= new File(fileNameWidthExtension
);
}
this.currentEmailFileName = emlName;
System.
out.
println("邮件消息的存储路径: " + fileNameWidthExtension
);
// 将邮件消息的内容写入ByteArrayOutputStream流中
message.writeTo(baos);
// 读取邮件消息流中的数据
// 存储到文件
saveFile(fileNameWidthExtension, in);
} catch (MessagingException e) {
e.printStackTrace();
e.printStackTrace();
}
}
/*
* 解析邮件
*/
private void parseMessage
(Message message
) throws IOException,
MessagingException {
Object content
= message.
getContent();
// 处理多部分邮件
if (content instanceof Multipart) {
handleMultipart((Multipart) content);
} else {
handlePart(message);
}
}
/*
* 解析Multipart
*/
private void handleMultipart(Multipart multipart)
for (int i = 0, n = multipart.getCount(); i < n; i++) {
handlePart(multipart.getBodyPart(i));
}
}
/*
* 解析指定part,从中提取文件
*/
private void handlePart
(Part part
) throws MessagingException,
IOException {
String disposition
= part.
getDisposition();
String contentType
= part.
getContentType();
String fileNameWidthExtension
= "";
// 获得邮件的内容输入流
// 没有附件的情况
if (disposition == null) {
if ((contentType.length() >= 10)
&& (contentType.toLowerCase().substring(0, 10)
.equals("text/plain"))) {
fileNameWidthExtension = this.receiverInfo.getAttachmentDir()
+ this.currentEmailFileName + ".txt";
} else if ((contentType.length() >= 9) // Check if html
&& (contentType.toLowerCase().substring(0, 9)
.equals("text/html"))) {
fileNameWidthExtension = this.receiverInfo.getAttachmentDir()
+ this.currentEmailFileName + ".html";
} else if ((contentType.length() >= 9) // Check if html
&& (contentType.toLowerCase().substring(0, 9)
.equals("image/gif"))) {
fileNameWidthExtension = this.receiverInfo.getAttachmentDir()
+ this.currentEmailFileName + ".gif";
} else if ((contentType.length() >= 11)
&& contentType.toLowerCase().substring(0, 11)
.equals("multipart/*")) {
// System.out.println("multipart body: " + contentType);
handleMultipart((Multipart) part.getContent());
} else { // Unknown type
// System.out.println("Other body: " + contentType);
fileNameWidthExtension = this.receiverInfo.getAttachmentDir()
+ this.currentEmailFileName + ".txt";
}
// 存储内容文件
System.
out.
println("保存邮件内容到:" + fileNameWidthExtension
);
saveFile(fileNameWidthExtension, sbis);
return;
}
// 各种有附件的情况
if (disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
name = getFileName(part);
// System.out.println("Attachment: " + name + " : "
// + contentType);
fileNameWidthExtension = this.receiverInfo.getAttachmentDir()
+ name;
} else if (disposition.equalsIgnoreCase(Part.INLINE)) {
name = getFileName(part);
// System.out.println("Inline: " + name + " : "
// + contentType);
fileNameWidthExtension = this.receiverInfo.getAttachmentDir()
+ name;
} else {
// System.out.println("Other: " + disposition);
}
// 存储各类附件
if (!fileNameWidthExtension.equals("")) {
System.
out.
println("保存邮件附件到:" + fileNameWidthExtension
);
saveFile(fileNameWidthExtension, sbis);
}
}
private String getFileName
(Part part
) throws MessagingException,
String fileName
= part.
getFileName();
fileName = MimeUtility.decodeText(fileName);
if (fileName != null) {
int index = fileName.lastIndexOf("/");
if (index != -1) {
name = fileName.substring(index + 1);
}
}
return name;
}
/**
* 保存文件内容
*
* @param fileName
* 文件名
* @param input
* 输入流
* @throws IOException
*/
// 为了放置文件名重名,在重名的文件名后面天上数字
// 先取得文件名的后缀
int lastDot = fileName.lastIndexOf(".");
String extension
= fileName.
substring(lastDot
);
fileName = fileName.substring(0, lastDot);
for (int i = 0; file.exists(); i++) {
// 如果文件重名,则添加i
file
= new File(fileName
+ i
+ extension
);
}
// 从输入流中读取数据,写入文件输出流
int aByte;
while ((aByte = bis.read()) != -1) {
bos.write(aByte);
}
// 关闭流
bos.flush();
bos.close();
bis.close();
}
/**
* 获得尖括号之间的字符
*
* @param str
* @return
* @throws Exception
*/
int i, j; // 用于标识字符串中的"<"和">"的位置
if (str == null) {
str = "error";
return str;
}
i = str.lastIndexOf("<");
j = str.lastIndexOf(">");
if (i != -1 && j != -1) {
str = str.substring(i + 1, j);
}
return str;
}
MailReceiverInfo receiverInfo = new MailReceiverInfo();
receiverInfo.setMailServerHost("pop.163.com");
receiverInfo.setMailServerPort("110");
receiverInfo.setValidate(true);
receiverInfo.setUserName("***");
receiverInfo.setPassword("***");
receiverInfo.setAttachmentDir("C:/temp/mail/");
receiverInfo.setEmailDir("C:/temp/mail/");
MailReceiver receiver = new MailReceiver(receiverInfo);
receiver.receiveAllMail();
}
}
/**
* 收邮件的基本信息
*/
class MailReceiverInfo {
// 邮件服务器的IP、端口和协议
private String mailServerHost
;
private String mailServerPort
= "110";
private String protocal
= "pop3";
// 登陆邮件服务器的用户名和密码
// 保存邮件的路径
private String attachmentDir
= "C:/temp/";
private String emailDir
= "C:/temp/";
private String emailFileSuffix
= ".eml";
// 是否需要身份验证
private boolean validate = true;
/**
* 获得邮件会话属性
*/
p.put("mail.pop3.host", this.mailServerHost);
p.put("mail.pop3.port", this.mailServerPort);
p.put("mail.pop3.auth", validate ? "true" : "false");
return p;
}
return protocal;
}
public void setProtocal
(String protocal
) {
this.protocal = protocal;
}
public String getAttachmentDir
() {
return attachmentDir;
}
public void setAttachmentDir
(String attachmentDir
) {
if (!attachmentDir.
endsWith(File.
separator)) {
attachmentDir
= attachmentDir
+ File.
separator;
}
this.attachmentDir = attachmentDir;
}
return emailDir;
}
public void setEmailDir
(String emailDir
) {
if (!emailDir.
endsWith(File.
separator)) {
emailDir
= emailDir
+ File.
separator;
}
this.emailDir = emailDir;
}
public String getEmailFileSuffix
() {
return emailFileSuffix;
}
public void setEmailFileSuffix
(String emailFileSuffix
) {
if (!emailFileSuffix.startsWith(".")) {
emailFileSuffix = "." + emailFileSuffix;
}
this.emailFileSuffix = emailFileSuffix;
}
public String getMailServerHost
() {
return mailServerHost;
}
public void setMailServerHost
(String mailServerHost
) {
this.mailServerHost = mailServerHost;
}
public String getMailServerPort
() {
return mailServerPort;
}
public void setMailServerPort
(String mailServerPort
) {
this.mailServerPort = mailServerPort;
}
return password;
}
public void setPassword
(String password
) {
this.password = password;
}
return userName;
}
public void setUserName
(String userName
) {
this.userName = userName;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
}
/**
* 邮件身份认证器,在发送邮件时使用
*/
// 登陆发送邮件服务器的用户名
// 登陆发送邮件服务器的密码
this.userName = userName;
this.password = password;
}
/**
* 覆盖父类的该方法,获得密码认证器
*/
}
return password;
}
public void setPassword
(String password
) {
this.password = password;
}
return userName;
}
public void setUserName
(String userName
) {
this.userName = userName;
}
}