首页 > 代码库 > 第七讲:解析邮件内容

第七讲:解析邮件内容

第七讲:解析邮件内容

一、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=http://www.mamicode.com/"/receivedMail/displayHeader" scrolling="no">"font-family:Microsoft YaHei;font-size:14px;">
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);
					}
					out.print("附件:");
					out.print("<a href=http://receivedMail//HandleAttach?>"+>下面的文件是在用户点击上述的连接时就会自动的现在文件:
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();
		}
	}
}