JavaMail入門第五篇 解析郵件


上一篇JavaMail入門第四篇 接收郵件中,控制台打印出的內容,我們無法閱讀,其實,讓我們自己來解析一封復雜的郵件是很不容易的,郵件里面格式、規范復雜得很。不過,我們所用的瀏覽器內置了解析各種數據類型的數據處理模塊,我們只需要在把數據流傳輸給瀏覽器之前明確地指定該數據流屬於哪種數據類型即可,之后一切的解析操作由瀏覽器自動幫我們完成。下面這張圖可以很好的說明解析郵件的步驟

1、調用Message對象的getFrom、getSubject等方法,可以得到郵件的發件人和主題等信息,調用getContentType方法得到郵件的類型;

2、通過Message.getContentType方法的返回值判斷郵件類型,並調用Message.getContent方法得到郵件內容。如果郵件類型為"text/plain"或者"text/html",表示郵件內容為純文本,此時調用Message對象的getContent方法得到郵件內容,然后將返回對象的類型轉換成String輸出給顯示軟件即可。如果郵件類型為"multipart/*",表示郵件內容是一個復合類型,此時需將Message.getContent方法復合的對象轉換成Multipart。

3、調用Multipart對象的getCount方法檢測Multipart對象中封裝了多少個BodyPart對象,並通過for循環逐一取出Multipart對象中的每個BodyPart對象進行處理。

4、在處理每個BodyPart對象時,首先調用BodyPart對象的getContentType方法得到它的MIME類型,然后根據MIME類型作出如下三種情況的處理:

  當MIME類型為"text/*"時,表示BodyPart對象中保存的是純文本數據,如上圖中的"text/plain",此時第一BodyPart對象的getContent方法並將返回的對象轉換成String輸出給顯示軟件顯示即可。

  當MIME類型表示的是圖片、聲音或者是附件等二進制數據時,如上圖中的"image/gif"時,此時應調用BodyPart對象的getDataHandler方法得到了封裝了數據的DataHanlder對象,然后調用DataHandler對象的getInputStream方法獲得與數據相關聯的InputStream對象,通過這個InputStream對象中即可獲得原始的二進制數據內容。

  當MIME類型為"multipart/mixed"時,表示BodyPart對象中保存的是一個復合MIME消息,此時應調用BodyPart對象的getContent方法得到封裝復合MIME消息的對象並將它轉換成Multipart類型,接着重復第3和第4個步驟操作對Multipart對象進行遞歸調用。

下面來編寫一個接收並解析帶有附件的程序

POP3Help.java

 1 package mail;
 2 
 3 import java.util.Properties;
 4 
 5 import javax.mail.Folder;
 6 import javax.mail.Session;
 7 import javax.mail.Store;
 8 
 9 public class POP3Help {
10     public static Folder getFolder(String host, String username, String password) {
11         Properties prop = new Properties();
12         prop.setProperty("mail.store.protocol", "pop3");
13         prop.setProperty("mail.pop3.host", host);
14 
15         Session mailSession = Session.getDefaultInstance(prop, null);
16         mailSession.setDebug(false);
17 
18         try {
19             Store store = mailSession.getStore("pop3");
20             store.connect(host, username, password);
21             Folder folder = store.getFolder("inbox");
22             folder.open(Folder.READ_WRITE);
23             return folder;
24         } catch (Exception e) {
25             e.printStackTrace();
26         }
27 
28         return null;
29     }
30 }

該類用來連接和登錄POP3服務器,並返回代表郵件夾的Folder對象

 

index.html

 1 <html>
 2   <head>
 3     <title>login.html</title>
 4   </head>
 5   <body>
 6     <form action="login.jsp" method="post">
 7         主機名:<input name="host" type="text"><br/>
 8         用戶名:<input name="username" type="text"><br/>
 9         密碼:<input name="password" type="password"><br/>
10         <input type="submit" value="提交"> 
11         <input type="reset" value="重置">
12     </form>
13   </body>
14 </html>

登錄頁面,需要用戶填寫郵件服務器的主機名,用戶名和密碼

 

login.jsp

 1 <%@ page import="javax.mail.*,mail.*"
 2  contentType="text/html;charset=GB2312" %>
 3 <%
 4     String host = request.getParameter("host");      
 5       String username = request.getParameter("username");
 6       String password = request.getParameter("password");
 7       String from = "";
 8       String subject = "";    
 9       Folder folder = POP3Help.getFolder(host,username,password);
10       session.setAttribute("folder",folder);
11       Message [] messages = folder.getMessages();
12       
13       for(int i=0;i<messages.length;i++)
14       {
15           try
16           {
17               from = messages[i].getFrom()[0].toString();
18             subject = messages[i].getSubject();
19             out.print(i + 1);
20 %>
21             發件人地址:<%=from %>  郵件主題:<%=subject %>                
22             <a href="displayMsg.jsp?msgnum=<%=i+1%>">查看郵件</a><br/>
23 <%
24         }
25             catch(Exception e){}
26           }
27 %>

獲取郵件夾中的所有郵件

 

displayMsg.jsp

1 <frameset rows="25%,*">
2     <frame src="/mailDemo/DisplayHead?msgnum=<%=request.getParameter("msgnum")%>" scrolling="no">
3     <frame src="/mailDemo/DisplayContent?msgnum=<%=request.getParameter("msgnum")%>" scrolling="no">
4 </frameset>

用於展示郵件的信息

 

DisplayHead.java

 1 package mail;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.text.DateFormat;
 6 
 7 import javax.mail.BodyPart;
 8 import javax.mail.Folder;
 9 import javax.mail.Message;
10 import javax.mail.Multipart;
11 import javax.mail.internet.MimeUtility;
12 import javax.servlet.ServletException;
13 import javax.servlet.http.HttpServlet;
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16 import javax.servlet.http.HttpSession;
17 
18 @SuppressWarnings("serial")
19 public class DisplayHead extends HttpServlet {
20     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21         response.setContentType("text/html;charset=gb2312");
22         PrintWriter out = response.getWriter();
23         HttpSession session = request.getSession();
24         int msgnum = Integer.parseInt(request.getParameter("msgnum"));
25         Folder folder = (Folder) session.getAttribute("folder");
26 
27         try {
28             Message msg = folder.getMessage(msgnum);
29             String from = msg.getFrom()[0].toString();
30             String subject = msg.getSubject();
31             String sendDate = DateFormat.getInstance().format(msg.getSentDate());
32 
33             out.println("郵件主題:" + subject + "<br/>");
34             out.println("發件人:" + from + "<br/>");
35             out.println("發送日期:" + sendDate + "<br/><br/>");
36 
37             System.out.println("contentType:" + msg.getContentType());
38 
39             // 如果該郵件是組合型"multipart/*"則可能包含附件等
40             if (msg.isMimeType("multipart/*")) {
41                 Multipart mp = (Multipart) msg.getContent();
42 
43                 for (int i = 0; i < mp.getCount(); i++) {
44                     BodyPart bp = mp.getBodyPart(i);
45 
46                     // 如果該BodyPart對象包含附件,則應該解析出來
47                     if (bp.getDisposition() != null) {
48                         String filename = bp.getFileName();
49                         System.out.println("filename:" + filename);
50                         
51                         if (filename.startsWith("=?")) {
52                             // 把文件名編碼成符合RFC822規范
53                             filename = MimeUtility.decodeText(filename);
54                         }
55 
56                         // 生成打開附件的超鏈接
57                         out.print("附件:");
58                         out.print("<a href=HandleAttach?msgnum=" + msgnum + "&&bodynum=" + i + "&&filename=" + filename
59                                 + ">" + filename + "</a><br/>");
60                     }
61                 }
62             }
63         } catch (Exception e) {
64             e.printStackTrace();
65         }
66     }
67 }

用於顯示郵件頭內容

 

DisplayContent.java

 1 package mail;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.mail.BodyPart;
 6 import javax.mail.Folder;
 7 import javax.mail.Message;
 8 import javax.mail.Multipart;
 9 import javax.servlet.ServletException;
10 import javax.servlet.ServletOutputStream;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import javax.servlet.http.HttpSession;
15 
16 @SuppressWarnings("serial")
17 public class DisplayContent extends HttpServlet {
18     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
19         ServletOutputStream sos = response.getOutputStream();
20         HttpSession session = request.getSession();
21         int msgnum = Integer.parseInt(request.getParameter("msgnum"));
22         Folder folder = (Folder) session.getAttribute("folder");
23 
24         try {
25             Message msg = folder.getMessage(msgnum);
26             // 郵件類型不是mixed時,表示郵件中不包含附件,直接輸出郵件內容
27             if (!msg.isMimeType("multipart/mixed")) {
28                 response.setContentType("message/rfc822");
29                 msg.writeTo(sos);
30             } else {
31                 // 查找並輸出郵件中的郵件正文
32                 Multipart mp = (Multipart) msg.getContent();
33                 int bodynum = mp.getCount();
34                 for (int i = 0; i < bodynum; i++) {
35                     BodyPart bp = mp.getBodyPart(i);
36                     /*
37                      * MIME消息頭中不包含disposition字段, 並且MIME消息類型不為mixed時,
38                      * 表示當前獲得的MIME消息為郵件正文
39                      */
40                     if (!bp.isMimeType("multipart/mixed") && bp.getDisposition() == null) {
41                         response.setContentType("message/rfc822");
42                         bp.writeTo(sos);
43                     }
44                 }
45             }
46         } catch (Exception e) {
47             e.printStackTrace();
48         }
49     }
50 }

用於顯示郵件正文

 

HandleAttact.java

 1 package mail;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import javax.mail.BodyPart;
 6 import javax.mail.Folder;
 7 import javax.mail.Message;
 8 import javax.mail.Multipart;
 9 import javax.servlet.ServletException;
10 import javax.servlet.ServletOutputStream;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import javax.servlet.http.HttpSession;
15 
16 @SuppressWarnings("serial")
17 public class HandleAttach extends HttpServlet {
18     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
19         response.setContentType("text/html");
20         HttpSession session = request.getSession();
21         ServletOutputStream out = response.getOutputStream();
22 
23         int msgnum = Integer.parseInt(request.getParameter("msgnum"));
24         int bodynum = Integer.parseInt(request.getParameter("bodynum"));
25         String filename = request.getParameter("filename");
26         Folder folder = (Folder) session.getAttribute("folder");
27 
28         try {
29             Message msg = folder.getMessage(msgnum);
30 
31             // 將消息頭類型設置為附件類型
32             response.setHeader("Content-Disposition", "attachment;filename=" + filename);
33             
34             Multipart multi = (Multipart) msg.getContent();
35             BodyPart bodyPart = multi.getBodyPart(bodynum);
36             
37             InputStream is = bodyPart.getInputStream();
38             int c = 0;
39             while ((c = is.read()) != -1) {
40                 out.write(c);
41             }
42         } catch (Exception e) {
43             e.printStackTrace();
44         }
45     }
46 }

用於處理附件

 

web.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
 3       <display-name>mailDemo</display-name>
 4       <welcome-file-list>
 5         <welcome-file>index.html</welcome-file>
 6         <welcome-file>index.htm</welcome-file>
 7         <welcome-file>index.jsp</welcome-file>
 8         <welcome-file>default.html</welcome-file>
 9         <welcome-file>default.htm</welcome-file>
10         <welcome-file>default.jsp</welcome-file>
11       </welcome-file-list>
12   
13       <servlet> 
14         <servlet-name>DisplayHead</servlet-name> 
15         <servlet-class>mail.DisplayHead</servlet-class> 
16     </servlet>      
17     <servlet-mapping> 
18         <servlet-name>DisplayHead</servlet-name> 
19         <url-pattern>/DisplayHead</url-pattern> 
20     </servlet-mapping> 
21        
22     <servlet> 
23         <servlet-name>DisplayContent</servlet-name> 
24         <servlet-class>mail.DisplayContent</servlet-class> 
25     </servlet>      
26     <servlet-mapping> 
27         <servlet-name>DisplayContent</servlet-name> 
28         <url-pattern>/DisplayContent</url-pattern> 
29     </servlet-mapping>      
30        
31     <servlet> 
32         <servlet-name>HandleAttach</servlet-name> 
33         <servlet-class>mail.HandleAttach</servlet-class> 
34     </servlet>      
35     <servlet-mapping> 
36         <servlet-name>HandleAttach</servlet-name> 
37         <url-pattern>/HandleAttach</url-pattern> 
38     </servlet-mapping> 
39 </web-app>

 

 

首先啟動tomcat服務器,然后在瀏覽器中輸入http://localhost:8080/mailDemo/index.html

輸入用戶名跟密碼(這里需要填寫授權碼,什么是授權碼,它又是如何設置?

列出了郵件夾中所有的郵件

 

點擊查看郵件鏈接

點擊附件后面的文件名稱即可下載對應附件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM