packagebook.email;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.ByteArrayOutputStream;importjava.io.File;importjava.io.FileWriter;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.Reader;importjava.io.StringReader;importjava.io.UnsupportedEncodingException;importjava.util.Date;importjavax.mail.BodyPart;importjavax.mail.Flags;importjavax.mail.Folder;importjavax.mail.Message;importjavax.mail.MessagingException;importjavax.mail.Multipart;importjavax.mail.NoSuchProviderException;importjavax.mail.Part;importjavax.mail.Session;importjavax.mail.Store;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeUtility;/*** 邮件接收器,目前支持pop3协议。
* 能够接收文本、HTML和带有附件的邮件*/publicclassMailReceiver {//收邮件的参数配置privateMailReceiverInfo receiverInfo;//与邮件服务器连接后得到的邮箱privateStore store;//收件箱privateFolder folder;//收件箱中的邮件消息privateMessage[] messages;//当前正在处理的邮件消息privateMessage currentMessage;privateString currentEmailFileName;publicMailReceiver(MailReceiverInfo receiverInfo) {this.receiverInfo=receiverInfo;
}/*** 收邮件*/publicvoidreceiveAllMail()throwsException{if(this.receiverInfo==null){thrownewException("必须提供接收邮件的参数!");
}//连接到服务器if(this.connectToServer()) {//打开收件箱if(this.openInBoxFolder()) {//获取所有邮件this.getAllMail();this.closeConnection();
}else{thrownewException("打开收件箱失败!");
}
}else{thrownewException("连接邮件服务器失败!");
}
}/*** 登陆邮件服务器*/privatebooleanconnectToServer() {//判断是否需要身份认证MyAuthenticator authenticator=null;if(this.receiverInfo.isValidate()) {//如果需要身份认证,则创建一个密码验证器authenticator=newMyAuthenticator(this.receiverInfo.getUserName(),this.receiverInfo.getPassword());
}//创建sessionSession session=Session.getInstance(this.receiverInfo
.getProperties(), authenticator);//创建store,建立连接try{this.store=session.getStore(this.receiverInfo.getProtocal());
}catch(NoSuchProviderException e) {
System.out.println("连接服务器失败!");returnfalse;
}
System.out.println("connecting");try{this.store.connect();
}catch(MessagingException e) {
System.out.println("连接服务器失败!");returnfalse;
}
System.out.println("连接服务器成功");returntrue;
}/*** 打开收件箱*/privatebooleanopenInBoxFolder() {try{this.folder=store.getFolder("INBOX");//只读folder.open(Folder.READ_ONLY);returntrue;
}catch(MessagingException e) {
System.err.println("打开收件箱失败!");
}returnfalse;
}/*** 断开与邮件服务器的连接*/privatebooleancloseConnection() {try{if(this.folder.isOpen()) {this.folder.close(true);
}this.store.close();
System.out.println("成功关闭与邮件服务器的连接!");returntrue;
}catch(Exception e) {
System.out.println("关闭和邮件服务器之间连接时出错!");
}returnfalse;
}/*** 获取messages中的所有邮件
*@throwsMessagingException*/privatevoidgetAllMail()throwsMessagingException {//从邮件文件夹获取邮件信息this.messages=this.folder.getMessages();
System.out.println("总的邮件数目:"+messages.length);
System.out.println("新邮件数目:"+this.getNewMessageCount());
System.out.println("未读邮件数目:"+this.getUnreadMessageCount());//将要下载的邮件的数量。intmailArrayLength=this.getMessageCount();
System.out.println("一共有邮件"+mailArrayLength+"封");interrorCounter=0;//邮件下载出错计数器intsuccessCounter=0;for(intindex=0; index
");this.showMailBasicInfo();
getMail();//获取当前messageSystem.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("------------------");
}/*** 显示邮件的基本信息*/privatevoidshowMailBasicInfo()throwsException{
showMailBasicInfo(this.currentMessage);
}privatevoidshowMailBasicInfo(Message message)throwsException {
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"---密送人地址*/privateString getTOAddress()throwsException {returngetMailAddress("TO",this.currentMessage);
}privateString getCCAddress()throwsException {returngetMailAddress("CC",this.currentMessage);
}privateString getBCCAddress()throwsException {returngetMailAddress("BCC",this.currentMessage);
}/*** 获得邮件地址
*@paramtype 类型,如收件人、抄送人、密送人
*@parammimeMessage 邮件消息
*@return*@throwsException*/privateString getMailAddress(String type, Message mimeMessage)throwsException {
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);
}elseif(addtype.equals("CC")) {
address=(InternetAddress[]) mimeMessage
.getRecipients(Message.RecipientType.CC);
}else{
address=(InternetAddress[]) mimeMessage
.getRecipients(Message.RecipientType.BCC);
}if(address!=null) {for(inti=0; i
email="";
}else{
email=MimeUtility.decodeText(email);
}//再取得个人描述信息String personal=address[i].getPersonal();if(personal==null){
personal="";
}else{
personal=MimeUtility.decodeText(personal);
}//将个人描述信息与邮件地址连起来String compositeto=personal+"";//多个地址时,用逗号分开mailaddr+=","+compositeto;
}
mailaddr=mailaddr.substring(1);
}
}else{thrownewException("错误的地址类型!!");
}returnmailaddr;
}/*** 获得发件人的地址和姓名
*@throwsException*/privateString getFrom()throwsException {returngetFrom(this.currentMessage);
}privateString getFrom(Message mimeMessage)throwsException {
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+"";returnfromaddr;
}/*** 获取messages中message的数量
*@return*/privateintgetMessageCount() {returnthis.messages.length;
}/*** 获得收件箱中新邮件的数量
*@return*@throwsMessagingException*/privateintgetNewMessageCount()throwsMessagingException {returnthis.folder.getNewMessageCount();
}/*** 获得收件箱中未读邮件的数量
*@return*@throwsMessagingException*/privateintgetUnreadMessageCount()throwsMessagingException {returnthis.folder.getUnreadMessageCount();
}/*** 获得邮件主题*/privateString getSubject()throwsMessagingException {returngetSubject(this.currentMessage);
}privateString getSubject(Message mimeMessage)throwsMessagingException {
String subject="";try{//将邮件主题解码subject=MimeUtility.decodeText(mimeMessage.getSubject());if(subject==null){
subject="";
}
}catch(Exception exce) {
}returnsubject;
}/*** 获得邮件发送日期*/privateDate getSentDate()throwsException {returngetSentDate(this.currentMessage);
}privateDate getSentDate(Message mimeMessage)throwsException {returnmimeMessage.getSentDate();
}/*** 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false"*/privatebooleangetReplySign()throwsMessagingException {returngetReplySign(this.currentMessage);
}privatebooleangetReplySign(Message mimeMessage)throwsMessagingException {booleanreplysign=false;
String needreply[]=mimeMessage
.getHeader("Disposition-Notification-To");if(needreply!=null) {
replysign=true;
}returnreplysign;
}/*** 获得此邮件的Message-ID*/privateString getMessageId()throwsMessagingException {returngetMessageId(this.currentMessage);
}privateString getMessageId(Message mimeMessage)throwsMessagingException {return((MimeMessage) mimeMessage).getMessageID();
}/*** 判断此邮件是否已读,如果未读返回返回false,反之返回true*/privatebooleanisNew()throwsMessagingException {returnisNew(this.currentMessage);
}privatebooleanisNew(Message mimeMessage)throwsMessagingException {booleanisnew=false;
Flags flags=mimeMessage.getFlags();
Flags.Flag[] flag=flags.getSystemFlags();for(inti=0; i
isnew=true;break;
}
}returnisnew;
}/*** 判断此邮件是否包含附件*/privatebooleanisContainAttach()throwsException {returnisContainAttach(this.currentMessage);
}privatebooleanisContainAttach(Part part)throwsException {booleanattachflag=false;if(part.isMimeType("multipart/*")) {//如果邮件体包含多部分Multipart mp=(Multipart) part.getContent();//遍历每部分for(inti=0; i
String disposition=bodyPart.getDisposition();if((disposition!=null)&&((disposition.equals(Part.ATTACHMENT))||(disposition
.equals(Part.INLINE)))){
attachflag=true;
}elseif(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;
}
}
}
}elseif(part.isMimeType("message/rfc822")) {
attachflag=isContainAttach((Part) part.getContent());
}returnattachflag;
}/*** 获得当前邮件*/privatevoidgetMail()throwsException {try{this.saveMessageAsFile(currentMessage);this.parseMessage(currentMessage);
}catch(IOException e) {thrownewIOException("保存邮件出错,检查保存路径");
}catch(MessagingException e) {thrownewMessagingException("邮件转换出错");
}catch(Exception e) {
e.printStackTrace();thrownewException("未知错误");
}
}/*** 保存邮件源文件*/privatevoidsaveMessageAsFile(Message message) {try{//将邮件的ID中尖括号中的部分做为邮件的文件名String oriFileName=getInfoBetweenBrackets(this.getMessageId(message)
.toString());//设置文件后缀名。若是附件则设法取得其文件后缀名作为将要保存文件的后缀名,//若是正文部分则用.htm做后缀名String emlName=oriFileName;
String fileNameWidthExtension=this.receiverInfo.getEmailDir()+oriFileName+this.receiverInfo.getEmailFileSuffix();
File storeFile=newFile(fileNameWidthExtension);for(inti=0; storeFile.exists(); i++) {
emlName=oriFileName+i;
fileNameWidthExtension=this.receiverInfo.getEmailDir()+emlName+this.receiverInfo.getEmailFileSuffix();
storeFile=newFile(fileNameWidthExtension);
}this.currentEmailFileName=emlName;
System.out.println("邮件消息的存储路径:"+fileNameWidthExtension);//将邮件消息的内容写入ByteArrayOutputStream流中ByteArrayOutputStream baos=newByteArrayOutputStream();
message.writeTo(baos);//读取邮件消息流中的数据StringReader in=newStringReader(baos.toString());//存储到文件saveFile(fileNameWidthExtension, in);
}catch(MessagingException e) {
e.printStackTrace();
}catch(Exception e) {
e.printStackTrace();
}
}/** 解析邮件*/privatevoidparseMessage(Message message)throwsIOException,
MessagingException {
Object content=message.getContent();//处理多部分邮件if(contentinstanceofMultipart) {
handleMultipart((Multipart) content);
}else{
handlePart(message);
}
}/** 解析Multipart*/privatevoidhandleMultipart(Multipart multipart)throwsMessagingException,
IOException {for(inti=0, n=multipart.getCount(); i
handlePart(multipart.getBodyPart(i));
}
}/** 解析指定part,从中提取文件*/privatevoidhandlePart(Part part)throwsMessagingException, IOException {
String disposition=part.getDisposition();
String contentType=part.getContentType();
String fileNameWidthExtension="";//获得邮件的内容输入流InputStreamReader sbis=newInputStreamReader(part.getInputStream());//没有附件的情况if(disposition==null) {if((contentType.length()>=10)&&(contentType.toLowerCase().substring(0,10)
.equals("text/plain"))) {
fileNameWidthExtension=this.receiverInfo.getAttachmentDir()+this.currentEmailFileName+".txt";
}elseif((contentType.length()>=9)//Check if html&&(contentType.toLowerCase().substring(0,9)
.equals("text/html"))) {
fileNameWidthExtension=this.receiverInfo.getAttachmentDir()+this.currentEmailFileName+".html";
}elseif((contentType.length()>=9)//Check if html&&(contentType.toLowerCase().substring(0,9)
.equals("image/gif"))) {
fileNameWidthExtension=this.receiverInfo.getAttachmentDir()+this.currentEmailFileName+".gif";
}elseif((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;
}//各种有附件的情况String name="";if(disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
name=getFileName(part);//System.out.println("Attachment: " + name + " : "//+ contentType);fileNameWidthExtension=this.receiverInfo.getAttachmentDir()+name;
}elseif(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);
}
}privateString getFileName(Part part)throwsMessagingException,
UnsupportedEncodingException {
String fileName=part.getFileName();
fileName=MimeUtility.decodeText(fileName);
String name=fileName;if(fileName!=null) {intindex=fileName.lastIndexOf("/");if(index!=-1) {
name=fileName.substring(index+1);
}
}returnname;
}/*** 保存文件内容
*@paramfileName 文件名
*@paraminput 输入流
*@throwsIOException*/privatevoidsaveFile(String fileName, Reader input)throwsIOException {//为了放置文件名重名,在重名的文件名后面天上数字File file=newFile(fileName);//先取得文件名的后缀intlastDot=fileName.lastIndexOf(".");
String extension=fileName.substring(lastDot);
fileName=fileName.substring(0, lastDot);for(inti=0; file.exists(); i++) {//如果文件重名,则添加ifile=newFile(fileName+i+extension);
}//从输入流中读取数据,写入文件输出流FileWriter fos=newFileWriter(file);
BufferedWriter bos=newBufferedWriter(fos);
BufferedReader bis=newBufferedReader(input);intaByte;while((aByte=bis.read())!=-1) {
bos.write(aByte);
}//关闭流bos.flush();
bos.close();
bis.close();
}/*** 获得尖括号之间的字符
*@paramstr
*@return*@throwsException*/privateString getInfoBetweenBrackets(String str)throwsException {inti, j;//用于标识字符串中的""的位置if(str==null) {
str="error";returnstr;
}
i=str.lastIndexOf("
j=str.lastIndexOf(">");if(i!=-1&&j!=-1){
str=str.substring(i+1, j);
}returnstr;
}publicstaticvoidmain(String[] args)throwsException {
MailReceiverInfo receiverInfo=newMailReceiverInfo();
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=newMailReceiver(receiverInfo);
receiver.receiveAllMail();
}
}