2012-10-30 43 views
31

Tôi đang cố truy cập tài khoản gmail của mình và truy xuất thông tin của tất cả các email chưa đọc từ đó.Lấy tất cả các email chưa đọc bằng cách sử dụng javamail với giao thức POP3

Tôi đã viết mã của mình sau khi giới thiệu nhiều liên kết. Tôi đang đưa ra một vài liên kết để tham khảo.

Send & Receive emails through a GMail account using Java

Java Code to Receive Mail using JavaMailAPI

Để kiểm tra mã của tôi, tôi đã tạo một tài khoản Gmail. Tôi đã nhận được 4 tin nhắn từ Gmail. Tôi chạy ứng dụng của mình sau khi kiểm tra số lượng thư. Điều đó cho thấy kết quả chính xác. 4 thư chưa đọc. Tất cả thông tin đã được hiển thị (ví dụ: ngày, người gửi, nội dung, chủ đề, v.v.)

Sau đó, tôi đăng nhập vào tài khoản mới của mình, đọc một trong các email và chạy lại ứng dụng của tôi. Hiện tại, số lượng thư chưa đọc phải là 3, nhưng nó hiển thị "Số thư chưa đọc: 0"

Tôi đang sao chép mã ở đây.

public class MailReader 

{ 

    Folder inbox; 

    // Constructor of the calss. 

    public MailReader() { 
     System.out.println("Inside MailReader()..."); 
     final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; 

     /* Set the mail properties */ 

     Properties props = System.getProperties(); 
     // Set manual Properties 
     props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY); 
     props.setProperty("mail.pop3.socketFactory.fallback", "false"); 
     props.setProperty("mail.pop3.port", "995"); 
     props.setProperty("mail.pop3.socketFactory.port", "995"); 
     props.put("mail.pop3.host", "pop.gmail.com"); 

     try 

     { 

      /* Create the session and get the store for read the mail. */ 

      Session session = Session.getDefaultInstance(
        System.getProperties(), null); 

      Store store = session.getStore("pop3"); 

      store.connect("pop.gmail.com", 995, "[email protected]", 
        "paasword"); 

      /* Mention the folder name which you want to read. */ 

      // inbox = store.getDefaultFolder(); 
      // inbox = inbox.getFolder("INBOX"); 
      inbox = store.getFolder("INBOX"); 

      /* Open the inbox using store. */ 

      inbox.open(Folder.READ_ONLY); 

      /* Get the messages which is unread in the Inbox */ 

      Message messages[] = inbox.search(new FlagTerm(new Flags(
        Flags.Flag.SEEN), false)); 
      System.out.println("No. of Unread Messages : " + messages.length); 

      /* Use a suitable FetchProfile */ 
      FetchProfile fp = new FetchProfile(); 
      fp.add(FetchProfile.Item.ENVELOPE); 

      fp.add(FetchProfile.Item.CONTENT_INFO); 

      inbox.fetch(messages, fp); 

      try 

      { 

       printAllMessages(messages); 

       inbox.close(true); 
       store.close(); 

      } 

      catch (Exception ex) 

      { 
       System.out.println("Exception arise at the time of read mail"); 

       ex.printStackTrace(); 

      } 

     } 

     catch (MessagingException e) 
     { 
      System.out.println("Exception while connecting to server: " 
        + e.getLocalizedMessage()); 
      e.printStackTrace(); 
      System.exit(2); 
     } 

    } 

    public void printAllMessages(Message[] msgs) throws Exception 
    { 
     for (int i = 0; i < msgs.length; i++) 
     { 

      System.out.println("MESSAGE #" + (i + 1) + ":"); 

      printEnvelope(msgs[i]); 
     } 

    } 

    public void printEnvelope(Message message) throws Exception 

    { 

     Address[] a; 

     // FROM 

     if ((a = message.getFrom()) != null) { 
      for (int j = 0; j < a.length; j++) { 
       System.out.println("FROM: " + a[j].toString()); 
      } 
     } 
     // TO 
     if ((a = message.getRecipients(Message.RecipientType.TO)) != null) { 
      for (int j = 0; j < a.length; j++) { 
       System.out.println("TO: " + a[j].toString()); 
      } 
     } 
     String subject = message.getSubject(); 

     Date receivedDate = message.getReceivedDate(); 
     Date sentDate = message.getSentDate(); // receivedDate is returning 
               // null. So used getSentDate() 

     String content = message.getContent().toString(); 
     System.out.println("Subject : " + subject); 
     if (receivedDate != null) { 
      System.out.println("Received Date : " + receivedDate.toString()); 
     } 
     System.out.println("Sent Date : " + sentDate.toString()); 
     System.out.println("Content : " + content); 

     getContent(message); 

    } 

    public void getContent(Message msg) 

    { 
     try { 
      String contentType = msg.getContentType(); 
      System.out.println("Content Type : " + contentType); 
      Multipart mp = (Multipart) msg.getContent(); 
      int count = mp.getCount(); 
      for (int i = 0; i < count; i++) { 
       dumpPart(mp.getBodyPart(i)); 
      } 
     } catch (Exception ex) { 
      System.out.println("Exception arise at get Content"); 
      ex.printStackTrace(); 
     } 
    } 

    public void dumpPart(Part p) throws Exception { 
     // Dump input stream .. 
     InputStream is = p.getInputStream(); 
     // If "is" is not already buffered, wrap a BufferedInputStream 
     // around it. 
     if (!(is instanceof BufferedInputStream)) { 
      is = new BufferedInputStream(is); 
     } 
     int c; 
     System.out.println("Message : "); 
     while ((c = is.read()) != -1) { 
      System.out.write(c); 
     } 
    } 

    public static void main(String args[]) { 
     new MailReader(); 
    } 
} 

Tôi đã tìm kiếm trên google, nhưng tôi thấy rằng bạn nên sử dụng Flags.Flag.SEEN để đọc email chưa đọc. Nhưng điều đó không hiển thị kết quả chính xác trong trường hợp của tôi.

Ai đó có thể chỉ ra nơi tôi có thể đang phạm sai lầm?

Nếu bạn cần toàn bộ mã, tôi có thể chỉnh sửa bài đăng của mình.

Lưu ý: Tôi đã chỉnh sửa câu hỏi của mình để bao gồm toàn bộ mã thay vì đoạn trích mà tôi đã đăng trước đó.

+1

Không nên 'Tin nhắn tin nhắn []' là 'Thông báo [tin nhắn ]'? – berbt

+1

Thực ra cả hai đều hợp lệ. Đọc các câu trả lời trên [tại đây] (http://stackoverflow.com/a/1200681/1777090) để biết giải thích chi tiết :) @berbt –

+3

Một chút kiến ​​thức bất ngờ mới. Cảm ơn các liên kết! – berbt

Trả lời

12

Mã của bạn sẽ hoạt động. Bạn cũng có thể sử dụng phương thức Folder.getUnreadMessageCount() nếu tất cả những gì bạn muốn là đếm.

JavaMail chỉ có thể cho bạn biết Gmail đang nói gì. Có lẽ Gmail nghĩ rằng tất cả những tin nhắn đó đã được đọc? Có lẽ giao diện web của Gmail đang đánh dấu những tin nhắn đó được đọc? Có lẽ bạn có ứng dụng khác đang giám sát thư mục cho thư mới?

Thử đọc một tin nhắn chưa đọc với JavaMail và xem có thay đổi số lượng không.

Bạn có thể thấy hữu ích khi bật gỡ lỗi phiên để bạn có thể thấy phản hồi IMAP thực tế mà Gmail đang trả về; xem JavaMail FAQ.

+0

Xin chào Bill, cảm ơn sự giúp đỡ. Tôi không muốn chỉ số lượng email chưa đọc. Những gì tôi cần là tất cả các email chưa đọc. Nó chỉ là một chương trình demo, nhưng cuối cùng tôi muốn làm việc với tập tin đính kèm của email nhận được trong dự án chính của tôi. Tôi đã thử sử dụng phương thức getUnreadMessageCount() trên hộp thư đến của mình. Nhưng nó luôn trả về -1. Vì vậy, điều đó không hoạt động trong trường hợp của tôi. Tôi sẽ chỉnh sửa câu hỏi của tôi và đăng toàn bộ mã của tôi ở đây. Bởi vì tôi nghĩ có điều gì đó đang xảy ra ở đâu đó. –

+5

Xin chào, tôi đã tìm ra vấn đề là gì .. Như bạn đã nói, tôi đã thử gỡ lỗi và thấy rằng Gmail đã trả về những kết quả đó. Tôi đã thay đổi cài đặt tài khoản Gmail của mình từ tab Chuyển tiếp và POP/IMAP. Vì vậy, bây giờ nó đang hoạt động đúng. Cảm ơn vì sự giúp đỡ. :) –

7

Thay đổi inbox.open(Folder.READ_ONLY); thành inbox.open(Folder.READ_WRITE); Nó sẽ thay đổi thư của bạn là đã đọc trong hộp thư đến.

+1

bạn có chắc chắn rằng nó hoạt động với pop3? trong trường hợp của tôi thì không. –

+1

Nó đã làm việc tốt cho tôi. Bạn đã sử dụng cấu hình nào? – user1791574

1

Lá cờ đúng để sử dụng là

Flags.Flag.RECENT 
+0

Mặc dù thực tế, JavaDoc cho [Thư mụC# getNewMessageCount] (http://docs.oracle.com/javaee/5/api/javax/mail/Folder.html#getNewMessageCount()) nói rằng nó kiểm tra cờ RECENT để xác định thư mới, Gmail thực sự sử dụng cờ SEEN để đánh dấu thư đã đọc. – jFrenetic

1
Flags seen = new Flags(Flags.Flag.RECENT); 
FlagTerm unseenFlagTerm = new FlagTerm(seen, false); 
messages = inbox.search(unseenFlagTerm); 
6

Bạn không thể tìm nạp thư chưa đọc bằng POP3. Từ JavaMail API:

POP3 không hỗ trợ cờ vĩnh viễn (xem Thư mục.getPermanentFlags()). Trong số cụ thể, cờ Flags.Flag.RECENT sẽ không bao giờ được đặt cho POP3 thư. Tùy thuộc vào ứng dụng để xác định thư nào trong hộp thư POP2 là "mới".

Bạn có thể sử dụng giao thức IMAP và sử dụng cờ SEEN như thế này:

public Message[] fetchMessages(String host, String user, String password, boolean read) { 
    Properties properties = new Properties(); 
    properties.put("mail.store.protocol", "imaps"); 

    Session emailSession = Session.getDefaultInstance(properties); 
    Store store = emailSession.getStore(); 
    store.connect(host, user, password); 

    Folder emailFolder = store.getFolder("INBOX"); 
    // use READ_ONLY if you don't wish the messages 
    // to be marked as read after retrieving its content 
    emailFolder.open(Folder.READ_WRITE); 

    // search for all "unseen" messages 
    Flags seen = new Flags(Flags.Flag.SEEN); 
    FlagTerm unseenFlagTerm = new FlagTerm(seen, read); 
    return emailFolder.search(unseenFlagTerm); 
} 

Một điều cần ghi nhận là POP3 không xử lý thư mục. IMAP nhận thư mục, POP3 chỉ nhận Hộp thư đến. Thông tin thêm tại: How to retrieve gmail sub-folders/labels using POP3?

Các vấn đề liên quan