2015-07-06 68 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內容之前去掉開頭的內容。還有其他方法可以做到這一點嗎?當然。這是軟件。總有另一種方式。但正如我所說的,它們並不是那麼多具有可預測結果的算法,因爲它們是啓發式的,有時可能有效並且有時會失敗。你必須決定你願意接受哪種失敗,併爲你關心的案例創建啓發式方法。 –

相關問題