javamail收取郵箱郵件

JavaMail可以使用POP3協議接受郵件,可用來實現郵件發佈文章功能。

那麼具體該怎麼做呢?這就必須先要明白帶附件的郵件的格式。

當收到郵件後進行解析,我們可以看到如下的郵件代碼(注意爲了便於閱讀,已經將分隔符替換爲比較容易閱讀的格式):

Received: from 127.0.0.1 by FMS4711; Fri, 25 Jul 2008 13:02:36 +0800
Date: Fri, 25 Jul 2008 13:02:36 +0800
From: "beansoft"
To: "hp"
Subject: =?gb2312?B?wb249ri9vP4=?=
Message-ID: <[email protected]>
X-mailer: Foxmail 6, 13, 102, 15 [cn]
Mime-Version: 1.0

Content-Type: multipart/mixed;
    boundary="===========分割一============"

This is a multi-part message in MIME format.

--===========分割一============
  Content-Type: multipart/alternative;
    boundary="===========分割2================="

  --===========分割2=================
  Content-Type: text/plain;
    charset="gb2312"
  Content-Transfer-Encoding: 7bit

  Body

  --===========分割2=================
  Content-Type: text/html;
    charset="gb2312"
  Content-Transfer-Encoding: 7bit

 
 
 
    href="BLOCKQUOTE{margin-Top: 0px; margin-Bottom: 0px; margin-Left: 2em}"
  rel=stylesheet>

Body
  face=Verdana size=2>
 
 

 

--===========分割2=================--

--===========分割一============
Content-Type: application/octet-stream;
    name="String2Java.jpg"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
    filename="String2Java.jpg"

/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
oAKKKKACiiigAooooA//2Q==

--===========分割一============
Content-Type: application/octet-stream;
    name="FoxmailUpdate.log"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
    filename="FoxmailUpdate.log"

OAAAAPgb7GHGsCG8a8W48hC9ihdb8CcIlHlKXcYwNP+8dPRB30zrsI2K4TPJP0gYLB3Cua0JRtBL
g/z8XA5PJneuwd9Uiu0nEH4Iobo+12oK9hsKK7xFXYhw++a50FHQuCDXX5kpF2d6

--===========分割一============--

 

 

它對應JavaMail的Message對象,一個Message對象又會有多個子對象如MultiPart對象,更特殊的是整個郵件內容爲一個大的MultiPart,然而郵件的正文則在嵌套的一個子MultiPart中,如果不瞭解這種組織結構,就可能無法正確獲得郵件的正文。此結構如下圖所示:

 

 

郵件 Message

 

 

 

 

 

 

頭部 ( 主題 , 發件人信息等 )

 

 

 

MultiPart 郵件全部內容 , 包含正文和附件

 

 

 

 

正文 MultiPart

 

 

 

 

 

 

文本正文 text/plain

 

 

 

 

Content-Type: text/plain;charset="gb2312"

 

 

 

 

HTML 網頁格式 text/html

 

 

 

 

Content-Type: text/html;charset="gb2312"

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

附件 1

 

 

 

 

 

 

Content-Type: application/octet-stream;

       name="String2Java.jpg"

Content-Transfer-Encoding: base64

Content-Disposition: attachment;

       filename="String2Java.jpg"

 

 

 

 

 

 

 

 

 

附件 2

 

 

 

 

 

 

Content-Type: application/octet-stream;

       name="FoxmailUpdate.log"

Content-Transfer-Encoding: base64

Content-Disposition: attachment;

       filename="FoxmailUpdate.log"

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

有了這些資料,我們就可以來解析郵件了,代碼如下:

 

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;

    import javax.mail.Address;
    import javax.mail.BodyPart;
    import javax.mail.FetchProfile;
    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.Part;
    import javax.mail.Session;
    import javax.mail.Store;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMultipart;

    /**
    * 郵件接受測試
    *
    */
    public class POP3MailReceiverTest {

        public POP3MailReceiverTest() {
            try {
                // 1. 設置連接信息, 生成一個 Session
                Properties props = new Properties();
                props.put("mail.transport.protocol", "pop3");// POP3 收信協議
                props.put("mail.pop.port", "110");
                // props.put("mail.debug", "true");// 調試

                Session session = Session.getInstance(props);

                // 2. 獲取 Store 並連接到服務器
                Store store = session.getStore("pop3");
                store.connect("localhost", "[email protected]", "1234");
                // 3. 通過 Store 打開默認目錄 Folder
                Folder folder = store.getDefaultFolder();// 默認父目錄
                if (folder == null) {

                    System.out.println("服務器不可用");
                    return;
                    // System.exit(1);
                }

    //            System.out.println("默認信箱名:" + folder.getName());
    //
    //            Folder[] folders = folder.list();// 默認目錄列表
    //
    //            System.out.println("默認目錄下的子目錄數: " + folders.length);

                Folder popFolder = folder.getFolder("INBOX");// 獲取收件箱
                popFolder.open(Folder.READ_WRITE);// 可讀郵件,可以刪郵件的模式打開目錄
                // 4. 列出來收件箱 下所有郵件
                Message[] messages = popFolder.getMessages();
                // 取出來郵件數
                int msgCount = popFolder.getMessageCount();
                System.out.println("共有郵件: " + msgCount + "封");

                // FetchProfile fProfile = new FetchProfile();// 選擇郵件的下載模式,
                // 根據網速選擇不同的模式
                // fProfile.add(FetchProfile.Item.ENVELOPE);
                // folder.fetch(messages, fProfile);// 選擇性的下載郵件

                // 5. 循環處理每個郵件並實現郵件轉爲新聞的功能
                for (int i = 0; i < msgCount; i++) {
                    Message msg = messages[i];// 單個郵件
                    // 發件人信息
                    Address[] froms = msg.getFrom();
                    if(froms != null) {
                        System.out.println("發件人信息:" + froms[0]);
                        InternetAddress addr = (InternetAddress)froms[0];
                        System.out.println("發件人地址:" + addr.getAddress());
                        System.out.println("發件人顯示名:" + addr.getPersonal());
                    }
                    News news = new News();// 生成新聞對象
                    System.out.println("郵件主題:" + msg.getSubject());
                    news.setTitle(msg.getSubject());

                    // getContent() 是獲取包裹內容, Part 相當於外包裝
                    Multipart multipart = (Multipart) msg.getContent();// 獲取郵件的內容, 就一個大包裹,
                                                                    // MultiPart
                                                                        // 包含所有郵件內容(正文+附件)
                    System.out.println("郵件共有" + multipart.getCount() + "部分組成");

                    // 依次處理各個部分
                    for (int j = 0, n = multipart.getCount(); j < n; j++) {
                        System.out.println("處理第" + j + "部分");
                        Part part = multipart.getBodyPart(j);//解包, 取出 MultiPart的各個部分, 每部分可能是郵件內容,
                        // 也可能是另一個小包裹(MultipPart)

                        // 判斷此包裹內容是不是一個小包裹, 一般這一部分是 正文 Content-Type: multipart/alternative
                        if (part.getContent() instanceof Multipart) {
                            Multipart p = (Multipart) part.getContent();// 轉成小包裹
                            System.out.println("小包裹中有" + p.getCount() + "部分");
                            // 列出小包裹中所有內容
                            for (int k = 0; k < p.getCount(); k++) {
                                System.out.println("小包裹內容:" + p.getBodyPart(k).getContent());
                                System.out.println("內容類型:"
                                        + p.getBodyPart(k).getContentType());
                                if(p.getBodyPart(k).getContentType().startsWith("text/plain")) {
                                    // 處理文本正文
                                    news.setBody(p.getBodyPart(k).getContent() + "");
                                } else {
                                    // 處理 HTML 正文
                                    news.setBody(p.getBodyPart(k).getContent() + "");
                                }
                            }
                        }

                        // Content-Disposition: attachment;    filename="String2Java.jpg"
                        String disposition = part.getDisposition();// 處理是否爲附件信息
                        if (disposition != null) {

                            System.out.println("發現附件: " + part.getFileName());
                            System.out.println("內容類型: " + part.getContentType());
                            System.out.println("附件內容:" + part.getContent());
                            java.io.InputStream in = part.getInputStream();// 打開附件的輸入流
                            // 讀取附件字節並存儲到文件中
                            java.io.FileOutputStream out = new FileOutputStream(part.getFileName());
                            int data;
                            while((data = in.read()) != -1) {
                                out.write(data);
                            }
                            in.close();
                            out.close();
                        }
                    }
                    // }
                    // TODO newsDAO.save(news); // 將郵件所攜帶的信息作爲新聞存儲起來

                    // 6. 刪除單個郵件, 標記一下郵件需要刪除, 不會真正執行刪除操作
                    // msg.setFlag(Flags.Flag.DELETED, true);
                }

                // 7. 關閉 Folder 會真正刪除郵件, false 不刪除
                popFolder.close(true);
                // 8. 關閉 store, 斷開網絡連接
                store.close();
            } catch (NoSuchProviderException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /**
         * @param args
         */
        public static void main(String[] args) {
            new POP3MailReceiverTest();

        }

    }

 轉自:http://blog.csdn.net/lenolong/archive/2009/03/08/3967446.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章