上一篇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
package mail;import java.util.Properties;import javax.mail.Folder;import javax.mail.Session;import javax.mail.Store;public class POP3Help { public static Folder getFolder(String host, String username, String password) { Properties prop = new Properties(); prop.setProperty("mail.store.protocol", "pop3"); prop.setProperty("mail.pop3.host", host); Session mailSession = Session.getDefaultInstance(prop, null); mailSession.setDebug(false); try { Store store = mailSession.getStore("pop3"); store.connect(host, username, password); Folder folder = store.getFolder("inbox"); folder.open(Folder.READ_WRITE); return folder; } catch (Exception e) { e.printStackTrace(); } return null; }}該類用來連接和登錄POP3服務器,並返回代表郵件夾的Folder對象
index.html
<html> <head> <title>login.html</title> </head> <body> <form action="login.jsp" method="post"> 主機名:<input name="host" type="text"><br/> 用戶名:<input name="username" type="text"><br/> 密碼:<input name="password" type="password"><br/> <input type="submit" value="提交"> <input type="reset" value="重置"> </form> </body></html>
登錄頁面,需要用戶填寫郵件服務器的主機名,用戶名和密碼
login.jsp
<%@ page import="javax.mail.*,mail.*" contentType="text/html;charset=GB2312" %><% String host = request.getParameter("host"); String username = request.getParameter("username"); String password = request.getParameter("password"); String from = ""; String subject = ""; Folder folder = POP3Help.getFolder(host,username,password); session.setAttribute("folder",folder); Message [] messages = folder.getMessages(); for(int i=0;i<messages.length;i++) { try { from = messages[i].getFrom()[0].toString(); subject = messages[i].getSubject(); out.print(i + 1);%> 發件人地址:<%=from %> 郵件主題:<%=subject %> <a href="displayMsg.jsp?msgnum=<%=i+1%>">查看郵件</a><br/><% } catch(Exception e){} }%>獲取郵件夾中的所有郵件
displayMsg.jsp
<frameset rows="25%,*"> <frame src="/mailDemo/DisplayHead?msgnum=<%=request.getParameter("msgnum")%>" scrolling="no"> <frame src="/mailDemo/DisplayContent?msgnum=<%=request.getParameter("msgnum")%>" scrolling="no"></frameset>用於展示郵件的信息
DisplayHead.java
package mail;import java.io.IOException;import java.io.PrintWriter;import java.text.DateFormat;import javax.mail.BodyPart;import javax.mail.Folder;import javax.mail.Message;import javax.mail.Multipart;import javax.mail.internet.MimeUtility;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;@SuppressWarnings("serial")public class DisplayHead extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=gb2312"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(); int msgnum = Integer.parseInt(request.getParameter("msgnum")); Folder folder = (Folder) session.getAttribute("folder"); try { Message msg = folder.getMessage(msgnum); String from = msg.getFrom()[0].toString(); String subject = msg.getSubject(); String sendDate = DateFormat.getInstance().format(msg.getSentDate()); out.println("郵件主題:" + subject + "<br/>"); out.println("發件人:" + from + "<br/>"); out.println("發送日期:" + sendDate + "<br/><br/>"); System.out.println("contentType:" + msg.getContentType()); // 如果該郵件是組合型"multipart/*"則可能包含附件等if (msg.isMimeType("multipart/*")) { Multipart mp = (Multipart) msg.getContent(); for (int i = 0; i < mp.getCount(); i++) { BodyPart bp = mp.getBodyPart(i); // 如果該BodyPart對象包含附件,則應該解析出來if (bp.getDisposition() != null) { String filename = bp.getFileName(); System.out.println("filename:" + filename); if (filename.startsWith("=?")) { // 把文件名編碼成符合RFC822規範filename = MimeUtility.decodeText(filename); } // 生成打開附件的超鏈接out.print("附件:"); out.print("<a href=HandleAttach?msgnum=" + msgnum + "&&bodynum=" + i + "&&filename=" + filename + ">" + filename + "</a><br/>"); } } } } catch (Exception e) { e.printStackTrace(); } }}用於顯示郵件頭內容
DisplayContent.java
package mail;import java.io.IOException;import javax.mail.BodyPart;import javax.mail.Folder;import javax.mail.Message;import javax.mail.Multipart;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;@SuppressWarnings("serial")public class DisplayContent extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream sos = response.getOutputStream(); HttpSession session = request.getSession(); int msgnum = Integer.parseInt(request.getParameter("msgnum")); Folder folder = (Folder) session.getAttribute("folder"); try { Message msg = folder.getMessage(msgnum); // 郵件類型不是mixed時,表示郵件中不包含附件,直接輸出郵件內容if (!msg.isMimeType("multipart/mixed")) { response.setContentType("message/rfc822"); msg.writeTo(sos); } else { // 查找並輸出郵件中的郵件正文Multipart mp = (Multipart) msg.getContent(); int bodynum = mp.getCount(); for (int i = 0; i < bodynum; i++) { BodyPart bp = mp.getBodyPart(i); /* * MIME消息頭中不包含disposition字段, 並且MIME消息類型不為mixed時, * 表示當前獲得的MIME消息為郵件正文*/ if (!bp.isMimeType("multipart/mixed") && bp.getDisposition() == null) { response.setContentType("message/rfc822"); bp.writeTo(sos); } } } } catch (Exception e) { e.printStackTrace(); } }}用於顯示郵件正文
HandleAttact.java
package mail;import java.io.IOException;import java.io.InputStream;import javax.mail.BodyPart;import javax.mail.Folder;import javax.mail.Message;import javax.mail.Multipart;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;@SuppressWarnings("serial")public class HandleAttach extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); HttpSession session = request.getSession(); ServletOutputStream out = response.getOutputStream(); int msgnum = Integer.parseInt(request.getParameter("msgnum")); int bodynum = Integer.parseInt(request.getParameter("bodynum")); String filename = request.getParameter("filename"); Folder folder = (Folder) session.getAttribute("folder"); try { Message msg = folder.getMessage(msgnum); // 將消息頭類型設置為附件類型response.setHeader("Content-Disposition", "attachment;filename=" + filename); Multipart multi = (Multipart) msg.getContent(); BodyPart bodyPart = multi.getBodyPart(bodynum); InputStream is = bodyPart.getInputStream(); int c = 0; while ((c = is.read()) != -1) { out.write(c); } } catch (Exception e) { e.printStackTrace(); } }}用於處理附件
web.xml
<?xml version="1.0" encoding="UTF-8"?><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"> <display-name>mailDemo</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>DisplayHead</servlet-name> <servlet-class>mail.DisplayHead</servlet-class> </servlet> <servlet-mapping> <servlet-name>DisplayHead</servlet-name> <url-pattern>/DisplayHead</url-pattern> </servlet-mapping> <servlet> <servlet-name>DisplayContent</servlet-name> <servlet-class>mail.DisplayContent</servlet-class> </servlet> <servlet-mapping> <servlet-name>DisplayContent</servlet-name> <url-pattern>/DisplayContent</url-pattern> </servlet-mapping> <servlet> <servlet-name>HandleAttach</servlet-name> <servlet-class>mail.HandleAttach</servlet-class> </servlet> <servlet-mapping> <servlet-name>HandleAttach</servlet-name> <url-pattern>/HandleAttach</url-pattern> </servlet-mapping> </web-app>
首先啟動tomcat服務器,然後在瀏覽器中輸入http://localhost:8080/mailDemo/index.html
輸入用戶名跟密碼(這裡需要填寫授權碼,什麼是授權碼,它又是如何設置?)
列出了郵件夾中所有的郵件
點擊查看郵件鏈接
點擊附件後面的文件名稱即可下載對應附件。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。