JavaMail接收邮件和发送邮件基本一致,大体上是把Transport换成了Store。不过和发送相比,难点是对接收到的邮件进行解析,不然看起来就跟乱码一样。之所以解析这一块难,就在于一封未知的邮件你不知道它的结构是怎样的,因此需要我们通过判断一步步解析。对于这一点,我也不是很清楚,所以下面我就瞎写一点基础的。
一.首先连接POP3服务器获取邮件
(1)创建Properties对象以及Session对象
// 创建一个有具体连接信息的Properties对象 Properties properties = new Properties(); properties.put("mail.store.protocal", protocal); properties.put("mail.pop3.host", pop3Server); // 使用Properties对象获得Session对象 Session session = Session.getInstance(properties); session.setDebug(false);
(2)利用Session对象获得Store对象,并连接pop3服务器
try { Store store = session.getStore(protocal); store.connect(pop3Server,username, password); //获取收件箱 Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); //以只读权限打开收件箱 /** * Folder.READ_ONLY:表示只读权限。 * Folder.READ_WRITE:表示可以修改并读取邮件夹中的邮件。 **/ //获取收件箱中的邮件 Message[] messages = folder.getMessages(); System.out.println("总的邮件数目:"+messages.length); System.out.println("新邮件数目:"+folder.getNewMessageCount()); System.out.println("未读邮件数目:"+folder.getUnreadMessageCount());
(3)对邮件进行一些处理后,然后进行格式化输出
for(int i=0;i<messages.length;i++){ HandleReceivedMail handleOneMail = new HandleReceivedMail((MimeMessage) messages[i]); System.out.println("Message "+ i + " : 主题:"+handleOneMail.getSubject()); System.out.println("Message "+ i + " : 时间:"+handleOneMail.getSendDate()); System.out.println("Message "+ i + " : 发件人:"+handleOneMail.getFrom()); // System.out.println("Message "+ i + " : Message-ID:"+handleOneMail.getMessageID()); System.out.println("Message "+ i + " : 回执:"+handleOneMail.getReplySign()); handleOneMail.getMailContent((Part)messages[i]); System.out.println("Message "+ i + " : 正文:"+handleOneMail.getBodyText()); System.out.println("Message "+ i + " : 附件:"+handleOneMail.isContainAttach((Part)messages[i])); System.out.println(); }
(4)关闭连接
//关闭连接 folder.close(false); store.close();
二.对获取到的邮件传入到一个处理类HandleReceivedMail中进行处理
(1)对主题等内容进行解密,防止中文乱码
public String changeEncode(String str){ try { if (str == null || "".equals(str)) str = ""; else str = MimeUtility.decodeText(str); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return str; }
(2)获取邮件主题
public String getSubject(){ String subject = ""; try { subject = changeEncode(mimeMessage.getSubject()); if(subject == null) subject = ""; return subject; } catch (MessagingException e) { e.printStackTrace(); } return null; }
(3)获取邮件发送时间
public String getSendDate(){ try { Date sendDate = mimeMessage.getSentDate(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return dateFormat.format(sendDate); } catch (MessagingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
(4)获取发件人姓名和地址
public String getFrom(){ try { InternetAddress[] address = (InternetAddress[]) mimeMessage.getFrom(); String person = address[0].getPersonal(); //姓名 if(person == null) person = ""; String from = address[0].getAddress(); //地址 if(from == null) from = ""; return person+"["+from+"]"; } catch (MessagingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
(5)获取邮件的Message-ID
public String getMessageID(){ try { return mimeMessage.getMessageID(); } catch (MessagingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
(6)判断邮件是否需要回执,需要返回“true”,否则返回“false”
public boolean getReplySign(){ try { String[] reply = mimeMessage.getHeader("Disposition-Notification-To"); if(reply != null) return true; } catch (MessagingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; }
(7)解析邮件
public void getMailContent(Part part){ try { String contentType = part.getContentType(); int nameIndex = contentType.indexOf("name"); boolean isContainTextAttach = false; //判断邮件中是否含有嵌套体 if(nameIndex != -1) isContainTextAttach = true; if(part.isMimeType("text/plain") && !isContainTextAttach) bodytext.append((String)part.getContent()); else if(part.isMimeType("text/html") && !isContainTextAttach) bodytext.append((String)part.getContent()); //对于HTML格式邮件,可以在前后加上标签<html><head>subject</head><body>bodytext</body></html>,保存为html格式文件(PS:未写) else if(part.isMimeType("message/rfc822")) getMailContent((Part) part.getContent()); else if(part.isMimeType("multipart/*")){ Multipart multipart = (Multipart) part.getContent(); int count = multipart.getCount(); for(int i=0;i<count;i++) getMailContent(multipart.getBodyPart(i)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
(8)正文文本内容
public String getBodyText(){ return bodytext.toString(); }
(9)判断是否包含附件
public boolean isContainAttach(Part part){ boolean attachflag = false; //是否有附件 try { String contentType = part.getContentType(); if(part.isMimeType("multipart/*")){ Multipart multipart = (Multipart) part.getContent(); for(int i=0;i<multipart.getCount();i++){ BodyPart bodyPart = multipart.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 bodytype = bodyPart.getContentType(); if(bodytype.toLowerCase().indexOf("application") !=-1) attachflag = true; if(bodytype.toLowerCase().indexOf("name") !=-1) attachflag = true; } } } else if(part.isMimeType("message/rfc822")) attachflag = isContainAttach((Part)part.getContent()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return attachflag; }
(10)保存附件到本地
(PS:未写)
三.测试代码
public static void main(String[] args) { ReceiveMail receiveMail = new ReceiveMail("pop3.163.com","pop3","[email protected]","******"); // ReceiveMail receiveMail = new ReceiveMail("pop.qq.com","pop3","[email protected]","******"); receiveMail.receiveAllMail(); }
注:1,关于POP3服务器,腾讯的和网易的写法还不一样,一个是:pop.qq.com,一个是:pop3.163.com
2,QQ邮箱如果短时间内大量连接或者重复连接的话,有可能会抽风,即使代码没问题也连不上,对于这种情况,要么等一会,要么换163或其他邮箱进行测试
附:
1,参考博文:http://xiangzhengyan.iteye.com/blog/85961
2,同样,我练习javamail所写的源代码放在了附件中,需要的可以参考下
时间: 2024-09-29 18:44:13