2015-07-06 17 views
1

我正在尝试从退回的邮件中读取附件的名称。这是我能够得到它的一种方式,但我想知道是否有更好的方法来做到这一点。这非常耗时。从退回的邮件中读取附件名称

​​

以下是完整的代码。

import java.io.BufferedReader; 
import java.io.StringReader; 
import java.util.Properties; 
import java.util.Scanner; 

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.Session; 
import javax.mail.Store; 
import javax.mail.search.FlagTerm; 

public class CheckingMail { 

    public static void check(String host, String storeType, String user, String password) 
    { 
     try { 
      Properties properties = new Properties(); 

      properties.put("mail.imap.host", host); 
      properties.put("mail.imap.port", "993"); 
      properties.put("mail.imap.starttls.enable", "true"); 

      Session emailSession = Session.getDefaultInstance(properties); 

      Store store = emailSession.getStore("imaps"); 

      store.connect(host, user, password); 

      Folder emailFolder = store.getFolder("INBOX"); 
      emailFolder.open(Folder.READ_WRITE); 

      System.out.println("emailFolder.hasNewMessages()---" + emailFolder.hasNewMessages()); 
      System.out.println("emailFolder.getNewMessageCount---" + emailFolder.getNewMessageCount()); 
      System.out.println("emailFolder.getUnreadMessageCount---" + emailFolder.getUnreadMessageCount()); 


      Message[] messages = emailFolder.search(new FlagTerm(new Flags(Flags.Flag.RECENT), false)); 
      System.out.println("messages.length---" + messages.length); 
      int bcnt = 0; 
      for (int i = 0, n = messages.length; i < n; i++) { 
       Message message = messages[i]; 
       if(message.getFrom()[0].toString().contains("MAILER-DAEMON")){ 
        bcnt++; 
       } 
       System.out.println("---------------------------------"); 
       System.out.println("Email Number " + (i + 1)); 
       System.out.println("Subject: " + message.getSubject()); 
       System.out.println("From: " + message.getFrom()[0]); 

       long start = System.currentTimeMillis(); 
       int index = -1; 
       BufferedReader reader = new BufferedReader(new StringReader(message.getContent().toString())); 
       String str = "" , filename = ""; 

       while ((str = reader.readLine()) != null) { 
        index = str.indexOf("filename"); 
        if(index >-1){ 
         filename = str.substring(index+9); 
         if (filename.length() > 0) System.out.println("Attachment : " + filename); 
        } 
       } 
       System.out.printf("Time : %d%n", System.currentTimeMillis() - start); 

       for(int j=0;j<message.getAllRecipients().length; j++){ 
        System.out.println("Recipients "+j+" : " + message.getAllRecipients()[j]); 
       } 
       System.out.println("Date: " + message.getSentDate()); 
      } 
      System.out.println("Bounce count : " + bcnt); 
      emailFolder.close(false); 
      store.close(); 

     } catch (NoSuchProviderException e) { 
      e.printStackTrace(); 
     } catch (MessagingException e) { 
      e.printStackTrace(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 

     String host = "imap.mail.yahoo.com"; 
     String mailStoreType = "imap"; 
     String username = "[email protected]"; 
     String password = "*****"; 

     check(host, mailStoreType, username, password); 

    } 

} 

的实例邮件

Sorry, we were unable to deliver your message to the following address. 

<[email protected]>: 
No MX or A records for yahoo.fhdf 

--- Below this line is a copy of the message. 

Received: from [ip] with NNFMP; 02 Jul 2015 07:26:24 -0000 
Received: from [ip] with NNFMP; 02 Jul 2015 07:23:24 -0000 
Received: from [ip] with NNFMP; 02 Jul 2015 07:23:21 -0000 
Received: from [ip] with NNFMP; 02 Jul 2015 07:23:21 -0000 
Received: from [] with NNFMP; 02 Jul 2015 07:23:21 -0000 
X-Yahoo-Newman-Property: ymail-4 
X-Yahoo-Newman-Id: [email protected] 
X-YMail-OSG: ByrxKJsVM1ngLTK9ms.eLuFTCEl6w0XU0HtbGqwE70HR4CtF8BU_giAhODvLvMc 
NiITUbpoTi2nhfKQ0WnxsPY4KMJyCRONlErkMhBA8a_bi7HLGeUqj53lPEgJ9oZtyTxykF4OVqw8 
e3Y0LO_rgeE49pQzvjFDNmE7L3kAePyzTbWfPv7Vper3tC8kWTTU21W5POlCB7LQ38FJoMsGOtSq 
qRjYLEILpy6xk34mPTwiSXkIb8iU.-- 
Received: by 217.12.9.9; Thu, 02 Jul 2015 07:23:21 +0000 
Date: Thu, 2 Jul 2015 07:23:20 +0000 (UTC) 
From: test <[email protected]> 
Reply-To: test <[email protected]> 
To: "[email protected]" <[email protected]> 
Message-ID: <[email protected]> 
Subject: 
MIME-Version: 1.0 
Content-Type: multipart/mixed; 
    boundary="----=_Part_1267464_969780179.1435821801286" 
Content-Length: 293584 

------=_Part_1267464_969780179.1435821801286 
Content-Type: multipart/alternative; 
    boundary="----=_Part_1267463_786603392.1435821801283" 

------=_Part_1267463_786603392.1435821801283 
Content-Type: text/plain; charset=UTF-8 
Content-Transfer-Encoding: 7bit 



------=_Part_1267463_786603392.1435821801283 
Content-Type: text/html; charset=UTF-8 
Content-Transfer-Encoding: 7bit 

<html><body><div style="color:#000; background-color:#fff; font-family:HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, Sans-Serif;font-size:16px"><div id="yui_3_16_0_1_1435820944162_7576"><br></div></div></body></html> 
------=_Part_1267463_786603392.1435821801283-- 

------=_Part_1267464_969780179.1435821801286 
Content-Type: application/pdf 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment; filename=img-211134632-0001.pdf 
Content-ID: <[email protected]> 

JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PAovQ3JlYXRvciAoWGVyb3ggV29ya0NlbnRyZSA1MjMw 
+0

这样一个退回邮件的例子会有所帮助。 – RealSkeptic

+0

@RealSkeptic我已经添加了一个反弹邮件示例 – Ace

+1

我认为您的方法的主要问题是缺乏可靠性 - 邮件可能包含与附件无关的单词“文件名”。如果所有退回的消息都与示例类似,我可能会删除所有行,直到嵌入的副本,然后将其解析为消息并处理该消息。这会更可靠,但不一定更高效。但并非所有的反弹看起来都一样,甚至不会给你一个完整的消息副本。 – RealSkeptic

回答

1

正如JavaMail FAQ解释,有一个标准,这样退回的邮件,但并非所有服务器实现的标准。你找到了一个这样的服务器。常见问题解答还有其他一些可能有用的提示,但你几乎陷入了启发式问题。如果您经常使用不支持该标准的特定邮件服务器,则可以通过识别来自此类服务器的退回邮件来使您的启发式更智能,更可靠。

例如,在上面的示例反弹消息中,消息的整个原始MIME内容似乎包含在内。您可以只提取该部分并使用MimeMessage constructor解析它,并更容易提取文件名。

+0

您是不是要找这样的事情 '的InputStream流=新ByteArrayInputStream的(。message.getContent()的toString()的getBytes(Charset.forName( “UTF-8”))); 的MimeMessage味精=新的MimeMessage(emailSession,流);' 是否有任何其他方式从退回的邮件阅读附件名称和其他细节。正如你所说的,并非所有的服务器都实现了反弹邮件的标准,有些甚至没有附件的名称。 – Ace

+1

是的,有点像这样,但是你必须在包含消息的MIME内容之前去掉开头的内容。还有其他方法可以做到这一点吗?当然。这是软件。总有另一种方式。但正如我所说的,它们并不是那么多具有可预测结果的算法,因为它们是启发式的,有时可能有效并且有时会失败。你必须决定你愿意接受哪种失败,并为你关心的案例创建启发式方法。 –

相关问题