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

简介:

当时我们只能在控制台中输出获取到邮件中的原始内容,里面有繁杂的邮件头格式和内容,也有被重新编码后的邮件正文等等,这些原始内容都是我们不能直接读懂的。这,确实没什么意思…

于是,我们需要根据一定的格式和方法将获取到的邮件进行解析,转换成我们平时在 Outlook 或者一些网页上看到的邮件那样子,当然是我们能看懂的啦。

不过,要我们掌握如何对邮件中复杂的 MIME 格式规范进行准确解析,那是相当地不简单,怎么办?这里我们简单地利用 Tomcat 服务器和 Servlet 、JSP 编程技术来简化这一过程,其实,最重要的角色还是浏览器,因为我们只需要将邮件中的原始内容的 MIME 的数据类型(例如message/rfc822 和 text/html )清楚地告知浏览器就可以了。由浏览器从本机注册表中查询到该用哪一种处理方式来处理这些数据,以便于在浏览器中显示出来。

可能这样说着比较难理解,下面是实际操作:

1、用 test_hao@sina.cn 邮箱向 testhao@126.com 邮箱发送一封正文中图文并茂的邮件,如下图:readMails01 

2、我们登录收到邮件的 testhao@126.com 邮箱中接收这封邮件,并读取、显示在浏览器中;

3、由于需要将邮件的原始内容传输给浏览器进行显示,需要用到 Tomcat 服务器以及 Servlet 、JSP 编程技术,由于邮件中的邮件头格式(text/html )与邮件正文的格式(message/rfc822)一般都不同,因此需要两个 Web 页面来分别指定各自的数据类型。但是在这里我们灵活变通一下,使用 HTML 将一个 Web 页面划分成两个帧,这就达到在同一 Web 页面中使用两种数据类型的需求了;

4、基于上述内容,我们的程序如下:

编写两个 Servlet 程序:ShowMessageContent.java 和 ShowMessageHeader.java ,从文件名种明显可以看出它们分别是负责将邮件正文内容、邮件头信息传输给浏览器进行解析并显示;

而另一个 showMessagePage.jsp 页面则用于登录对应的 POP3 服务器接收邮件,并把 Web 页面划分成两个帧;

此外,Servlet 程序需要在 web.xml 文件中配置 Servlet 信息。

程序代码:

showMessagePage.jsp 


 
 
  1. <%@ page language="java" 
  2.     import="java.util.*,javax.mail.*" 
  3.     pageEncoding="gbk"%>  
  4.  
  5. <%  
  6.     // 连接pop3服务器的主机名、协议、用户名、密码  
  7.     String pop3Server = "pop3.126.com";  
  8.     String protocol = "pop3";  
  9.     String user = "testhao";  
  10.     String pwd = "123456";  
  11.           
  12.     // 创建一个有具体连接信息的Properties对象  
  13.     Properties props = new Properties();  
  14.     props.setProperty("mail.store.protocol", protocol);  
  15.     props.setProperty("mail.pop3.host", pop3Server);  
  16.       
  17.     // 使用Properties对象获得Session对象  
  18.     Session mailSession = Session.getDefaultInstance(props,null);  
  19.     mailSession.setDebug(true);  
  20.  
  21.     try{          
  22.         // 利用Session对象获得Store对象,并连接pop3服务器  
  23.         Store store = mailSession.getStore();  
  24.         store.connect(pop3Server, user, pwd);  
  25.           
  26.         // 获得邮箱内的邮件夹Folder对象,以"读-写"打开  
  27.         Folder folder = store.getFolder("inbox");  
  28.         folder.open(Folder.READ_WRITE);  
  29.  
  30.         // 将上面读取到的邮件夹folder设置为属性  
  31.         session.setAttribute("folder", folder);  
  32.  
  33.     }catch(Exception e){  
  34.         e.printStackTrace();  
  35.     }  
  36.  
  37.     // 下面用 HTML 将 web 页面分成两帧,便于针对邮件的  
  38.     // "text/html"邮件头以及"message/rfc822" 格式的邮件正文  
  39. %>  
  40.  
  41. <frameset rows="25%,*">  
  42.     <frame src="/JavaMail/showMessageHeader" scrolling="no">  
  43.     <frame src="/JavaMail/showMessageContent" scrolling="no">  
  44. </frameset> 

ShowMessageHeader.java 


 
 
  1. import java.io.*;  
  2. import java.text.DateFormat;  
  3. import javax.mail.*;  
  4. import javax.servlet.*;  
  5. import javax.servlet.http.*;  
  6.  
  7. public class ShowMessageHeader 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.         Folder folder = (Folder)session.getAttribute("folder");  
  17.  
  18.         try{          
  19.             // 作为实验,这里只获取第 1 封邮件  
  20.             Message message = folder.getMessage(1);  
  21.             String from = (message.getFrom()[0]).toString();  
  22.             String subject = message.getSubject();  
  23.             String sendDate = DateFormat.getInstance().format(message.getSentDate());  
  24.  
  25.             out.println("邮件主题:" + subject + "<br/>");  
  26.             out.println("发件人地址:" + from + "<br/>");  
  27.             out.println("发送日期:" + sendDate + "<br/>");  
  28.  
  29.         }catch(Exception e){  
  30.             e.printStackTrace();  
  31.         }  
  32.     }  

ShowMessageContent.java 


 
 
  1. import java.io.*;  
  2. import javax.mail.*;  
  3. import javax.servlet.*;  
  4. import javax.servlet.http.*;  
  5.  
  6. public class ShowMessageContent extends HttpServlet  
  7. {  
  8.     public void doGet(HttpServletRequest request,  
  9.         HttpServletResponse response) throws ServletException, IOException  
  10.     {  
  11.         // 获取输出流、Session 会话对象、邮件夹 Folder 对象  
  12.         ServletOutputStream out = response.getOutputStream();  
  13.         HttpSession session = request.getSession();  
  14.         Folder folder = (Folder)session.getAttribute("folder");  
  15.  
  16.         try{          
  17.             // 取得邮件夹中的邮件,并设置MIME类型  
  18.             // 为"message/rfc822"格式,交给浏览器处理  
  19.             Message message = folder.getMessage(1);  
  20.             response.setContentType("message/rfc822");  
  21.             message.writeTo(out);  
  22.  
  23.         }catch(Exception e){  
  24.             e.printStackTrace();  
  25.         }  
  26.     }  

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>ShowMessageHeader</servlet-name> 
  10.         <servlet-class>ShowMessageHeader</servlet-class> 
  11.     </servlet> 
  12.       
  13.     <servlet-mapping> 
  14.         <servlet-name>ShowMessageHeader</servlet-name> 
  15.         <url-pattern>/showMessageHeader</url-pattern> 
  16.     </servlet-mapping> 
  17.       
  18.     <servlet> 
  19.         <servlet-name>ShowMessageContent</servlet-name> 
  20.         <servlet-class>ShowMessageContent</servlet-class> 
  21.     </servlet> 
  22.       
  23.     <servlet-mapping> 
  24.         <servlet-name>ShowMessageContent</servlet-name> 
  25.         <url-pattern>/showMessageContent</url-pattern> 
  26.     </servlet-mapping>      
  27.       
  28. </web-app> 

测试过程:

1、编译两个 Servlet 程序,将生成的 .class 文件放到 JavaMail\WEB-INF\classes 文件中;

2、配置 web.xml 文件;

3、开启 Tomcat 服务器,在浏览器地址栏输入(根据我的具体情况)http://localhost:8080/JavaMail/showMessagePage.jsp ,得到以下结果:

readMails02

 

看一下我们登录到邮箱时看到的结果:

readMails03

readMails04 

小结:

1、由于在 ShowMessageContent.java 程序中调用了 response.setContentType("message/rfc822"); 所以上面正文部分的中文乱码了,大概是因为要设置字符集才行,不过我们已经设置为了 message/rfc822 类型,所以无法再重新设置。看来应该将纯文本和内嵌的图片分开来显示,看看这个功能能不能在下一篇文章中解决掉;

2、很明显 126 邮箱将内嵌的图片作为附件来解析了,这是服务器的问题,各个不同的邮件服务器可能都有不同的解析结果。

3、我们还可以在控制台中输出的信息中看一下程序与 POP3 服务器通信、传输数据的过程。

 



本文转自 xxxx66yyyy 51CTO博客,原文链接:http://blog.51cto.com/haolloyin/355854,如需转载请自行联系原作者

相关文章
|
6月前
|
监控 Java 应用服务中间件
Tomcat log日志解析
理解和解析Tomcat日志文件对于诊断和解决Web应用中的问题至关重要。通过分析 `catalina.out`、`localhost.log`、`localhost_access_log.*.txt`、`manager.log`和 `host-manager.log`等日志文件,可以快速定位和解决问题,确保Tomcat服务器的稳定运行。掌握这些日志解析技巧,可以显著提高运维和开发效率。
479 13
|
7月前
|
数据采集 Web App开发 监控
深度解析:使用ChromeDriver和webdriver_manager实现无头浏览器爬虫
在现代网络爬虫实践中,动态网页加载和反爬虫机制增加了数据采集的难度。采用无头浏览器技术(如Selenium与ChromeDriver)可有效模拟用户行为、执行JavaScript,获取动态内容。通过设置代理IP、伪装User-Agent和处理Cookies,提升爬虫隐蔽性和稳定性。该方案适用于电商价格监控、社交媒体数据采集和招聘信息抓取等场景,实现更高效的数据获取。
566 2
深度解析:使用ChromeDriver和webdriver_manager实现无头浏览器爬虫
|
7月前
|
数据采集 Web App开发 存储
深度解析:使用 Headless 模式 ChromeDriver 进行无界面浏览器操作
本文介绍了基于无界面浏览器(如ChromeDriver)和代理IP技术的现代爬虫解决方案,以应对传统爬虫面临的反爬机制和动态加载内容等问题。通过Selenium驱动ChromeDriver,并结合亿牛云爬虫代理、自定义Cookie和User-Agent设置,实现高效的数据采集。代码示例展示了如何配置ChromeDriver、处理代理认证、添加Cookie及捕获异常,确保爬虫稳定运行。性能对比显示,Headless模式下的ChromeDriver在数据采集成功率、响应时间和反爬规避能力上显著优于传统爬虫。该方案广泛应用于电商、金融和新闻媒体等行业。
412 0
深度解析:使用 Headless 模式 ChromeDriver 进行无界面浏览器操作
|
10月前
|
域名解析 缓存 网络协议
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
|
10月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
201 1
|
人工智能 前端开发 Java
【Tomcat源码分析】启动过程深度解析 (二)
本文深入探讨了Tomcat启动Web应用的过程,重点解析了其加载ServletContextListener及Servlet的机制。文章从Bootstrap反射调用Catalina的start方法开始,逐步介绍了StandardServer、StandardService、StandardEngine、StandardHost、StandardContext和StandardWrapper的启动流程。每个组件通过Lifecycle接口协调启动,子容器逐层启动,直至整个服务器完全启动。此外,还详细分析了Pipeline及其Valve组件的作用,展示了Tomcat内部组件间的协作机制。
【Tomcat源码分析】启动过程深度解析 (二)
|
11月前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
204 4
|
12月前
|
XML 编解码 JavaScript
从浏览器的解析规则认识XSS防御
从浏览器的解析规则认识XSS防御
133 3
|
11月前
|
JavaScript API
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
深入解析JS中的visibilitychange事件:监听浏览器标签间切换的利器
563 0
|
6月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
600 29

热门文章

最新文章

推荐镜像

更多
  • DNS