一、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); } 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(); } } }
第七讲:解析邮件内容