第七講:解析郵件內容

第七講:解析郵件內容

一、JavaMail解析郵件內容的流程


二、解析郵件內容

2.1 解析普通郵件內容

如果Message.getContentType方法返回的MIME類型爲"text/*"則表示郵件內容爲文本內容,此時直接調用Message.getContent方法把郵件內容保存了一個String對象中輸出給瀏覽器即可。但是現實郵件中會有HTML格式的郵件內容時,郵件發送程序爲了防止有些郵件閱讀軟件不能顯示處理HTML格式的數據,通常都會用兩類型分別爲"text/plain"和"text/html"的MIME消息封裝HTML代碼。因此對於這兩種類型要通過判斷之後方可顯示。

下面使用例子來進行判斷:
當含有"text/plain"和"text/html"中時使用Message.getContentType返回的類型爲"multipart/alternative"

public class Demo1 extends HttpServlet {

	String host = "pop3.163.com";
	String protocol = "pop3";
	String username = "XXX";
	String password = "XXX";

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=gb2312");
		PrintWriter out = response.getWriter();
		
		Properties props = new Properties();
		props.setProperty("mail.store.protocol", protocol);
		props.setProperty("mail.pop3.host", host);
		javax.mail.Session session = javax.mail.Session.getInstance(props);
		session.setDebug(false);
		
		try {
			Store store = session.getStore(protocol);
			store.connect(host, username, password);
			Folder folder = store.getFolder("inbox");
			folder.open(Folder.READ_WRITE);
			
			Message[] msgs = folder.getMessages();
			for(int i=0; i< msgs.length; i++){
				String from = msgs[i].getFrom()[0].toString();
				String subject = msgs[i].getSubject();
				out.print("第"+(i+1)+"封郵件<br/>");
				out.print("發件人:"+from);
				out.print("主題:"+subject);
				/**
				 * 檢查是否是"multipart/alternative"類型,
				 * 如果是取出其中的"text/html"類型的消息
				 */
				if(msgs[i].isMimeType("multipart/alternative")){
					Multipart mp = (Multipart)msgs[i].getContent();
					int bodynum = mp.getCount();
					for(int j=0; j<bodynum; j++){
						if(mp.getBodyPart(j).isMimeType("text/html")){
							String content = (String)mp.getBodyPart(j).getContent();
							out.print("郵件內容:"+content+"<br/>");
							out.print("-------------------------------<br/>");
						}
						else{
							out.print("不支持的郵件類型<br/>");
						}
					}
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
2.2 解析“multipart/related”類型的郵件
郵件類型爲"multipart/related"的郵件正文中包括圖片,聲音等內嵌資源。IE瀏覽器顯示的類型就是"multipart/related",因此可以通過IE瀏覽器顯示郵件中的內容只需要將生成的文件名稱改爲html然後用瀏覽器打開即可。IE瀏覽器作爲郵件數據顯示工具式,不管郵件體中嵌套多少個內嵌資源,程序只需要向IE瀏覽器輸出郵件體中的數據,並告訴瀏覽器以"message/rfc822"的形式進行處理就可以了。那麼IE瀏覽器就會自動解析並且顯示這種形式的郵件數據。

public class Demo2 extends HttpServlet {
	String host = "pop3.163.com";
	String protocol = "pop3";
	String username = "XXX";
	String password = "XXX";
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		ServletOutputStream out = response.getOutputStream();
		
		Properties props = new Properties();
		props.setProperty("mail.store.protocol", protocol);
		props.setProperty("mail.pop3.host", host);
		javax.mail.Session session = javax.mail.Session.getInstance(props);
		session.setDebug(false);
		
		try {
			Store store = session.getStore(protocol);
			store.connect(host, username, password);
			Folder folder = store.getFolder("inbox");
			folder.open(Folder.READ_WRITE);
			
			/**
			 * 假設取得第一封郵件是"multipart/related"
			 * 則直接進行處理
			 */
			Message msg = folder.getMessage(0);
			response.setContentType("message/rfc822");
			msg.writeTo(System.out);
			msg.writeTo(out);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
2.3 使用IE解析正文需要注意的問題
一個IE瀏覽器只能處理一種數據類型,而我們在解析內嵌資源的郵件時,從郵件中解析出來的郵件頭信息通常是以"text/html"格式向輸出的,而郵件正文是以"message/rfc822"格式向IE瀏覽器輸出的。因此要想在瀏覽器中顯示符合人們閱讀習慣的郵件信息,即在同一個瀏覽器窗口中即顯示郵件頭信息又顯示郵件正文,就需要對瀏覽器窗口進行分幀,每個幀窗口顯示一種格式的郵件數據。
例如下面的jsp文件用於連接郵件服務器並且緩存Folder對象到會話對象Session中,該文件還定義了兩個證窗口分別用來顯示郵件頭和郵件正文。

<%@ page language="java" import="java.util.*" import="javax.mail.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

	String host = "pop3.163.com";
	String protocol = "pop3";
	String username = "XXX";
	String password = "XXX";
	Properties props = new Properties();
		props.setProperty("mail.store.protocol", protocol);
		props.setProperty("mail.pop3.host", host);
		javax.mail.Session mailSession = javax.mail.Session.getInstance(props);
		mailSession.setDebug(true);
		
		try {
			Store store = mailSession.getStore(protocol);
			store.connect(host, username, password);
			Folder folder = store.getFolder("inbox");
			folder.open(Folder.READ_WRITE);
			session.setAttribute("folder", folder);
		} catch (Exception e) {
			e.printStackTrace();
		}
%>

<frameset>
	<frame src="/receivedMail/displayHeader" scrolling="no">
	<frame src="/receivedMail/displayContent" scrolling="no">
</frameset>
2.4 解析郵件附件

在Web應用中解析包含附件的郵件時,只需要從Message對象中解析出保存附件數據的BodyPart對象,然後從BodyPart對象中得到附件的輸入流、附件的MIME類型和附件的文件名,並且這些信息輸出給IE瀏覽器。瀏覽器收到信息後,會根據數據的MIME類型彈出相應的對話框提示用戶下載或打開附件。

public class Demo3 extends HttpServlet {

	String host = "pop3.163.com";
	String protocol = "pop3";
	String username = "XXX";
	String password = "XXX";

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=gb2312");
		PrintWriter out = response.getWriter();
		
		Properties props = new Properties();
		props.setProperty("mail.store.protocol", protocol);
		props.setProperty("mail.pop3.host", host);
		javax.mail.Session mailSession = javax.mail.Session.getInstance(props);
		mailSession.setDebug(false);
		
		try {
			Store store = mailSession.getStore(protocol);
			store.connect(host, username, password);
			Folder folder = store.getFolder("inbox");
			folder.open(Folder.READ_WRITE);
			
			Message msg1 = folder.getMessage(1);
			request.getSession().setAttribute("message", msg1);
		
			String from = msg1.getFrom()[0].toString();
			String subject = msg1.getSubject();
			String sendDate = DateFormat.getInstance().format(msg1.getSentDate());
			out.print("發件人:"+from+"<br/>");
			out.print("主題:"+subject+"<br/>");
			out.print("發件日期:"+sendDate+"<br/>");
			
			Multipart mp = (Multipart)msg1.getContent();
			for(int i=0; i<mp.getCount(); i++){
				BodyPart bp =mp.getBodyPart(i);
				if(bp.getDisposition()!=null){
					String fileName = bp.getFileName();
					if(fileName.startsWith("=?")){
						fileName = MimeUtility.decodeText(fileName); //需要解析中文名稱的文件名(將中文名稱加入郵件時用encodeText)
					}
					out.print("附件:");
					out.print("<a href=\\receivedMail\\HandleAttach?>"+
					"bodynum="+ i +"&&filename= " + fileName + "</a><br/>");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
下面的文件是在用戶點擊上述的連接時就會自動的現在文件:
public class HandleAttach extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		HttpSession session = request.getSession();
		ServletOutputStream out = response.getOutputStream();
		
		int bodynum = Integer.parseInt(request.getParameter("bodynum"));
		String fileName = request.getParameter("filename");
		
		Message message = (Message)session.getAttribute("message");
		
		try {
			response.setHeader("Content-Disposition", "attachment;filename="+fileName);
			Multipart mp = (Multipart)message.getContent();
			BodyPart bp = mp.getBodyPart(bodynum);
			InputStream is = bp.getInputStream();
			
			int c=0;
			if((c = is.read())!= -1){
				out.write(c);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



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