`

JavaMail:在Web应用下完整接收、解析复杂邮件(转)

 
阅读更多

其实,让我们自己来解析一封复杂的邮件是很不容易的,邮件里面格式、规范复杂得很。幸运的是,我们所用的浏览器一定内置了解析各种数据类型的数据处理模块,我们只需要在把数据流传输给浏览器之前明确地指定该数据流属于哪种数据类型即可,之后一切的解析操作由浏览器自动帮我们完成。

现在我们想要像 Outlook 客户端或者登录网页邮箱那样子接收、查看邮件,而这些邮件中可能包含附件、正文中可能内嵌图片、音频等等。好吧,我们来实现一下吧。

程序结构:

1、mailboxLogin.html 文件用于提供一个用户登录界面,由用户填写 POP3 服务器主机名、用户名和密码;

2、connectServer.jsp 文件用于获取登录界面中的登录信息,并连接到 POP3 服务器,还要读取显示出邮箱中的所有邮件列表,再提供一个查看邮件详细内容的超链接;

3、showMails.jsp 文件用于将一个 Web 页面分成两帧,目的在上一篇文章中讲过,就是分别指定不同的 MIME 消息头类型来让浏览器解析、显示出邮件头内容和邮件正文内容;

4、ShowHeader.java 文件是处理邮件头内容的 Servlet 程序;

5、ShowContent.java 文件时处理邮件正文内容的 Servlet 程序;

6、HandleAttachments.java 文件是当从 ShowHeader.java 程序处理邮件头内容时,若发现该邮件包含附件,则交给 HandleAttachments.java 这个 Servlet 程序进行处理,它能够在邮件头中给出附件的文件名、超链接,所以用户可以点击下载。这是上篇文章中所缺乏的,也是这个程序实现中的重点!

7、web.xml 文件用于根据前面的 Servlet 程序来部署、配置相关的映射信息。

好吧,讲了那么多让人不知所云的东西,来点截图啊、代码啊最让我兴奋的了,因为截图、所有代码我保证都是完整的(或许自己尝试一下可以弄出更多的截图),嘻嘻…

我们依然需要 Tomcat 这个服务器,关于 JSP 、Servlet 编程技术、部署配置映射信息等方面的内容就不能多讲了。这里先说明,我们要登录的邮箱时 testhao@126.com ,用户名为 testhao ,密码为 123456,里面的邮件跟上篇文章重点截图一样,不过我自己多发送了一封包含3封附件的邮件哦,如下:(更多精彩截图,请继续看下文)

WebMail01

WebMail02

WebMail04

程序代码: 

mailboxLogin.html

  1. <hmtl> 
  2.     <head> 
  3.         <title>邮箱登录页面</title> 
  4.     </head> 
  5.     <body> 
  6.         <form action="connectServer.jsp" method="post"> 
  7.             POP3服务器主机名:<input name="pop3Server" type="text"></br> 
  8.             邮箱用户名:<input name="user" type="text"></br> 
  9.             邮箱密码:<input name="pwd" type="password"></br> 
  10.             <input type="submit" value="登录"> 
  11.             <input type="reset" value="重置"></br> 
  12.         </form> 
  13.     </body> 
  14. </html> 

connectServer.jsp

  1. <%@ page  
  2.     import="javax.mail.*,java.util.Properties" 
  3.     contentType="text/html;charset=gbk" %>  
  4.  
  5. <%  
  6.     String pop3Server = request.getParameter("pop3Server");  
  7.     String user = request.getParameter("user");  
  8.     String pwd = request.getParameter("pwd");  
  9.  
  10.     // 创建一个有具体连接信息的Properties对象  
  11.     Properties props = new Properties();  
  12.     props.setProperty("mail.store.protocol""pop3");  
  13.     props.setProperty("mail.pop3.host", pop3Server);  
  14.       
  15.     // 使用Properties对象获得Session对象  
  16.     Session mailSession = Session.getDefaultInstance(props);  
  17.     //mailSession.setDebug(true);  
  18.  
  19.     Folder folder = null;  
  20.     try{          
  21.         // 利用Session对象获得Store对象,并连接pop3服务器  
  22.         Store store = mailSession.getStore();  
  23.         store.connect(pop3Server, user, pwd);  
  24.           
  25.         // 获得邮箱内的邮件夹Folder对象,以"读-写"打开  
  26.         folder = store.getFolder("inbox");  
  27.         folder.open(Folder.READ_WRITE);  
  28.  
  29.     }catch(Exception e){  
  30.         e.printStackTrace();  
  31.     }  
  32. //  Folder folder = POP3Connect.getFolder(pop3Server,user,pwd);  
  33.     session.setAttribute("folder", folder);  
  34.  
  35.     String from = null;  
  36.     String subject = null;  
  37.     Message [] messages = folder.getMessages();  
  38.     int messageCounts = messages.length;  
  39.     for(int i = 0; i < messageCounts; i++)  
  40.     {  
  41.         try{  
  42.             from = messages[i].getFrom()[0].toString();  
  43.             subject = messages[i].getSubject();  
  44.             out.println("<B>邮件 " + (i+1) + "</B>");  
  45. %>  
  46.         </br>发件人地址:<%=from %></br>  
  47.         邮件主题:<%=subject %></br>  
  48.         <a href="showMails.jsp?msgnum=<%=i+1 %>">  
  49.         >> 查看邮件!!!</a></br></br>  
  50. <%  
  51.         }catch(Exception e){  
  52.             e.printStackTrace();  
  53.         }  
  54.     }  
  55. %> 

showMails.jsp

  1. <frameset rows="25%,*"> 
  2.     <frame src="/JavaMail/ShowHeader?msgnum=  
  3.             <%=request.getParameter("msgnum")%>scrolling="yes"> 
  4.     <frame src="/JavaMail/ShowContent?msgnum=  
  5.             <%=request.getParameter("msgnum")%>scrolling="yes"> 
  6. </frameset> 

ShowHeader.java

  1. import java.io.*;  
  2. import java.text.DateFormat;  
  3. import javax.mail.internet.MimeUtility;  
  4. import javax.mail.*;  
  5. import javax.servlet.*;  
  6. import javax.servlet.http.*;  
  7.  
  8. // 解析邮件头消息,包括判断是否有附件  
  9. public class ShowHeader extends HttpServlet  
  10. {  
  11.     public void doGet(HttpServletRequest request,  
  12.         HttpServletResponse response) throws ServletException, IOException  
  13.     {  
  14.         response.setContentType("text/html;charset=gbk");  
  15.         PrintWriter out = response.getWriter();  
  16.         HttpSession session = request.getSession();  
  17.  
  18.         Folder folder = (Folder)session.getAttribute("folder");  
  19.         int msgnum = Integer.parseInt(request.getParameter("msgnum"));  
  20.  
  21.         try{                      
  22.             Message message = folder.getMessage(msgnum);  
  23.             String from = (message.getFrom()[0]).toString();  
  24.             String subject = message.getSubject();  
  25.             String sentDate = DateFormat.getInstance().format(message.getSentDate());  
  26.  
  27.             out.println("邮件主题:" + subject + "<br/>");  
  28.             out.println("发件人地址:" + from + "<br/>");  
  29.             out.println("发送日期:" + sentDate + "<br/>");  
  30.               
  31.             // 如果该邮件是组合型"multipart/*"则可能包含附件等  
  32.             if(message.isMimeType("multipart/*"))  
  33.             {  
  34.                 Multipart multipart = (Multipart)message.getContent();  
  35.                 int bodyCounts = multipart.getCount();  
  36.                 for(int i = 0; i < bodyCounts; i++)  
  37.                 {  
  38.                     BodyPart bodypart = multipart.getBodyPart(i);  
  39.                     // 如果该BodyPart对象包含附件,则应该解析出来  
  40.                     if(bodypart.getDisposition() != null)  
  41.                     {  
  42.                         String filename = bodypart.getFileName();  
  43.                         if(filename.startsWith("=?"))  
  44.                         {  
  45.                             // 把文件名编码成符合RFC822规范  
  46.                             filename = MimeUtility.decodeText(filename);  
  47.                         }  
  48.                         // 生成打开附件的超链接  
  49.                         out.print("<B>附件 " + (i+1) + ":</B>");  
  50.                         out.println("<a href=HandleAttachments?msgnum="   
  51.                             + msgnum + "&&bodynum=" + i + "&&filename=" 
  52.                             + filename + ">" + filename + "</a></br>");  
  53.                     }  
  54.                 }  
  55.             }  
  56.         }catch(Exception e){  
  57.             e.printStackTrace();  
  58.         }  
  59.     }  

ShowContent.java

  1. import java.io.*;  
  2. import javax.mail.*;  
  3. import javax.servlet.*;  
  4. import javax.servlet.http.*;  
  5.  
  6. // 处理邮件的正文部分  
  7. public class ShowContent extends HttpServlet  
  8. {  
  9.     public void doGet(HttpServletRequest request,  
  10.         HttpServletResponse response) throws ServletException, IOException  
  11.     {  
  12.         // 获取输出流、Session 会话对象、邮件夹 Folder 对象  
  13.         ServletOutputStream out = response.getOutputStream();  
  14.         HttpSession session = request.getSession();  
  15.         Folder folder = (Folder)session.getAttribute("folder");  
  16.         int msgnum = Integer.parseInt(request.getParameter("msgnum"));  
  17.  
  18.         try{  
  19.             Message message = folder.getMessage(msgnum);  
  20.             if(!message.isMimeType("multipart/mixed"))  
  21.             {  
  22.                 // 若邮件类型不是"mixed"则表明不包含附件,  
  23.                 // 并设置类型让浏览器直接输出正文  
  24.                 response.setContentType("message/rfc822");  
  25.                 message.writeTo(out);  
  26.             }else{  
  27.                 // 如果是"mixed"型,则遍历所有BodyPart对象,  
  28.                 // 把不包含附件的邮件正文打印出来。  
  29.                 // 这是为了不让该程序既输出正文又传输附件大量的数据  
  30.                 Multipart multipart = (Multipart)message.getContent();  
  31.                 int bodyCounts = multipart.getCount();  
  32.                 for(int i = 0; i < bodyCounts; i++)  
  33.                 {  
  34.                     BodyPart bodypart = multipart.getBodyPart(i);  
  35.                     // 不是"mixed"型且不包含附件  
  36.                     if(!bodypart.isMimeType("multipart/mixed")   
  37.                         && bodypart.getDisposition() == null)  
  38.                     {  
  39.                         response.setContentType("message/rfc822");  
  40.                         bodypart.writeTo(out);                        
  41.                     }  
  42.                 }  
  43.             }  
  44.         }catch(Exception e){  
  45.             e.printStackTrace();  
  46.         }  
  47.     }  

HandleAttachments.java

  1. import java.io.*;  
  2. import javax.mail.*;  
  3. import javax.servlet.*;  
  4. import javax.servlet.http.*;  
  5.  
  6. // 处理邮件中的附件  
  7. public class HandleAttachments extends HttpServlet  
  8. {  
  9.     public void doGet(HttpServletRequest request,  
  10.         HttpServletResponse response) throws ServletException, IOException  
  11.     {  
  12.         response.setContentType("text/html;charset=gbk");  
  13.         PrintWriter out = response.getWriter();  
  14.         HttpSession session = request.getSession();  
  15.  
  16.         int msgnum = Integer.parseInt(request.getParameter("msgnum"));  
  17.         int bodynum = Integer.parseInt(request.getParameter("bodynum"));          
  18.         Folder folder = (Folder)session.getAttribute("folder");  
  19.         String filename = request.getParameter("filename");  
  20.  
  21.         try{  
  22.             Message message = folder.getMessage(msgnum);  
  23.             // 将消息头类型设置为附件类型  
  24.             response.setHeader("Content-Disposition",   
  25.                 "attachment;filename=" + filename);  
  26.  
  27.             Multipart multipart = (Multipart)message.getContent();  
  28.             BodyPart bodypart = multipart.getBodyPart(bodynum);  
  29.  
  30.             InputStream input = bodypart.getInputStream();  
  31.             int temp = 0;  
  32.             while((temp = input.read()) != -1)  
  33.             {  
  34.                 out.write(temp);  
  35.             }  
  36.         }catch(Exception e){  
  37.             e.printStackTrace();  
  38.         }  
  39.     }  

web.xml

  1. <?xml version="1.0" encoding="gb2312"?> 
  2.  
  3. <web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
  6.     version="2.4"> 
  7.       
  8.     <servlet> 
  9.         <servlet-name>ShowHeader</servlet-name> 
  10.         <servlet-class>ShowHeader</servlet-class> 
  11.     </servlet>      
  12.     <servlet-mapping> 
  13.         <servlet-name>ShowHeader</servlet-name> 
  14.         <url-pattern>/ShowHeader</url-pattern> 
  15.     </servlet-mapping> 
  16.        
  17.     <servlet> 
  18.         <servlet-name>ShowContent</servlet-name> 
  19.         <servlet-class>ShowContent</servlet-class> 
  20.     </servlet>      
  21.     <servlet-mapping> 
  22.         <servlet-name>ShowContent</servlet-name> 
  23.         <url-pattern>/ShowContent</url-pattern> 
  24.     </servlet-mapping>      
  25.        
  26.     <servlet> 
  27.         <servlet-name>HandleAttachments</servlet-name> 
  28.         <servlet-class>HandleAttachments</servlet-class> 
  29.     </servlet>      
  30.     <servlet-mapping> 
  31.         <servlet-name>HandleAttachments</servlet-name> 
  32.         <url-pattern>/HandleAttachments</url-pattern> 
  33.     </servlet-mapping> 
  34.       
  35. </web-app> 

测试过程:(其实就是精彩的截图啦)

WebMail03

 

WebMail05

WebMail06

WebMail07

WebMail08

好了,精彩截图没了吗?不是的,我们还要与 126 邮箱中的解析、显示效果比对一下,如下:

WebMail09

又是这个问题:

为什么我们明明才上传了 3 个附件啊(见最上面的图),这里显示为 4 个了。我猜测的原因在前面的文章中也说过了,它把邮件正文中的图片也解析为附件了,不同的邮件服务器在解析发送、接收、解析邮件时都有自己的方式、策略,这个不理了。不过话说回来,我们自己写的程序好像更加合理一点哦,直接显示 3 个附件,真好!

小结:

1、在这个基于 Tomcat 的 Web 应用中,只用解析邮件中的附件是新的知识,其他的都讲过了;

2、关于程序代码结构、内容是否高效的问题,在这些文章中都没有太多注意,原因是比较注重实现想要的功能,这个不足要意识到并且逐步改过来;

3、关于 JavaMail 邮件开发的学习似乎就到此告一段落了,从最原始的用 Windows 下的 telnet 程序连接服务器手工一条一条命令地发送、接收邮件,到自己写了个 GUI 程序封装这些邮件发送命令以达到真正的纯文本邮件发送的功能,再到学习 JavaMail API 更轻松的创建邮件内容、邮件发送、邮件接收、运用 Tomcat 和浏览器实现邮件的解析…

噢,好像是学习完了。但是,编程学习要达到卖油翁的“无他, 唯手熟尔”绝对是一条漫长艰苦的道路,在此源于大家互相交流、共同学习、一起进步!加油!!!

其实,有时间的话我们也可以扩展上面的程序,综合前面所有文章中的内容,实现一个能够发送邮件,上传图片、附件,以及接收、解析、查看邮件的综合应用…

我的相关文章:

图解使用Telnet程序手工发送邮件

简单的E-mail发送端程序的Java实现

图解使用telnet程序手工接收邮件及其过程

JavaMail:邮件发送以及sina、163、QQ服务器不同的解析结果(附图)

JavaMail:简单的邮件接收程序

JavaMail:利用Tomcat和浏览器解析邮件内容

本文出自 “蚂蚁” 博客,请务必保留此出处http://haolloyin.blog.51cto.com/1177454/357204

分享到:
评论

相关推荐

    基于JaVaMail的Web邮件客户端的设计与实现

    通过一个具体的案例来深入理解JavaMail在Web邮件客户端中的应用。例如,设计一个简单的Web邮件系统,包括用户注册、登录、发送邮件、接收邮件等功能,并结合实际需求,探讨如何更好地集成JavaMail API,提高系统的...

    javaMail发送和接收邮件

    JavaMail 是一个开源的 Java 库,用于在 Java 应用程序中发送和接收电子邮件。它提供了丰富的 API,使得开发者可以方便地与各种邮件服务器进行交互,支持 SMTP、POP3 和 IMAP 协议。本篇文章将深入探讨 JavaMail 的...

    JAVAMAIL 实例 + JAVAMAIL支持包 完整可运行实例

    将JAR包放入WEB-INF的LIB目录是Java Web应用的标准做法,这样可以让应用服务器在运行时找到这些依赖。 JavaMail API 主要包含以下几个关键组件: 1. **Properties**: 这是用来设置邮件服务器配置的,如SMTP服务器...

    开发JavaMail Web源码

    JavaMail 是一个强大的开源库,专门用于在Java应用程序中处理电子邮件。这个Web应用项目是基于JavaMail API构建的,提供了一种用户界面,使客户能够方便地与邮件服务器交互,执行一系列邮件操作。以下是该应用涉及的...

    javaMail详解

    JavaMail 是一个开源的Java库,它为Java开发者提供了一套API来处理电子邮件。这个库不仅支持SMTP(简单邮件传输协议)、POP3...无论是在企业级应用、Web服务还是移动应用中,JavaMail都是处理电子邮件任务的理想选择。

    javamail类库

    JavaMail 是一个强大的开源类库,它...总的来说,JavaMail是Java开发人员处理电子邮件不可或缺的工具,无论是在企业级应用中发送确认邮件、接收通知,还是在Web应用中实现邮件服务,JavaMail都能提供强大而灵活的支持。

    基于Javamail的邮件收发系统的实现.rar

    基于JavaMail的邮件收发系统是一种用于发送和接收电子邮件的应用程序,它基于JavaMail API来实现与邮件服务器的通信,并提供用户界面来进行邮件的管理和操作。以下是对该系统实现的描述: 用户界面: 系统提供了...

    大学毕业论文-—基于web的电子邮件系统邮件协议研究与系统功能实现.doc

    JavaMail 是一个基于 Java 的邮件处理 API,提供了邮件发送、接收和解析的功能。JavaMail 的实现原理是基于 Java 语言的邮件处理机制,使用了邮件协议(SMTP、POP3、IMAP)来实现邮件的发送和接收。 知识点2:...

    JavaMail API的两个jar文件

    除此之外,JavaMail API与其他Java EE组件(如Java Servlets和JavaServer Pages)有良好的集成,可以在Web应用程序中方便地处理邮件功能。 总的来说,JavaMail API是Java开发者处理邮件服务的强大工具,通过`mail....

    javamailjavamailjavamail

    JavaMail 是一个用于处理电子邮件的 Java 开发包,它提供了丰富的 API 使得开发者能够在 Java 应用程序中实现发送、接收和管理邮件的功能。JavaMail 的应用广泛,常见于 Web 应用程序中,例如用于发送密码重置邮件、...

    javamail相关的jar

    总之,JavaMail为Java程序员提供了一个强大的工具,简化了邮件处理任务,无论是在Web应用、桌面应用还是服务器端脚本中,都能方便地实现邮件功能。而 `activation.jar` 和 `mail.jar` 这两个库文件则是JavaMail功能...

    JavaMail结合JSP实现中文邮件收发系统.rar

    JavaMail结合JSP实现中文邮件收发系统是一个典型的Web应用开发案例,主要涉及Java后端技术和JSP(JavaServer Pages)前端技术,用于构建能够处理中文字符的电子邮件发送与接收功能。这一系统的实现依赖于JavaMail ...

    struts javamail jaf 三合一

    当这三者结合在一起时,比如在一个基于Struts的Web应用中集成邮件功能,开发者可以利用Struts的控制器层处理用户的邮件请求,通过Action调用JavaMail API发送邮件。同时,如果邮件包含附件,JAF可以处理这些附件的...

    邮件javamail包(activation.jar和mail.jar)

    JavaMail 是一个开源的 Java API,它允许 Java 程序员通过标准的协议(如 SMTP、POP3、IMAP)发送和接收...由于其丰富的功能和良好的跨平台性,JavaMail 在 Web 应用、服务端脚本、自动化任务等场景中都有广泛的应用。

    JAVA基于JAVA的电子邮件接收系统论文

    在本篇论文中,我们将深入探讨如何利用Java技术构建一个基于Java的电子邮件接收系统。Java是一种广泛应用于开发各种软件和网络应用的高级编程语言,其跨平台性、丰富的类库和强大的网络支持使得它成为构建电子邮件...

    javamail.jar

    JavaMail是Java编程环境中用于处理电子邮件的一套API,它提供了创建、发送和接收邮件的功能。在Java应用程序中,我们通常会用到两个关键的库文件:`activation.jar`和`mail.jar`。这两个JAR文件在Spring框架集成邮件...

    javamail-1_3_2-upd.zip

    JavaMail 是一个开源的 Java API,它为Java开发者提供了一套强大的邮件处理工具,使得开发者可以在Java应用程序中方便地收发电子邮件。这个“javamail-1_3_2-upd.zip”压缩包包含了JavaMail的1.3.2版本,这是一个...

    自己开发的JAVA Web Email邮件系统

    【标签】:“JAVA Email”指的是使用JAVA语言处理电子邮件的程序设计,这可能涉及到JavaMail API,这是一个开源库,为开发者提供了处理邮件的标准API,可以实现邮件的发送、接收和解析。邮件客户端则是用户与邮件...

    javaMail中的cos,jsf,JavaMail三个jar包

    虽然JavaMail主要用于处理邮件,但有时我们可能需要在Web应用中集成邮件服务,例如当用户提交表单时自动发送确认邮件。在这种情况下,jsf可以帮助我们在Web界面中触发邮件发送过程。不过,需要注意的是,JavaMail...

Global site tag (gtag.js) - Google Analytics