上一篇JavaMail入门第四篇 接收邮件中,控制台打印出的内容,我们无法阅读,其实,让我们自己来解析一封复杂的邮件是很不容易的,邮件里面格式、规范复杂得很。不过,我们所用的浏览器内置了解析各种数据类型的数据处理模块,我们只需要在把数据流传输给浏览器之前明确地指定该数据流属于哪种数据类型即可,之后一切的解析操作由浏览器自动帮我们完成。下面这张图可以很好的说明解析邮件的步骤

1、调用Message对象的getFrom、getSubject等方法,可以得到邮件的发件人和主题等信息,调用getContentType方法得到邮件的类型;

2、通过Message.getContentType方法的返回值判断邮件类型,并调用Message.getContent方法得到邮件内容。如果邮件类型为"text/plain"或者"text/html",表示邮件内容为纯文本,此时调用Message对象的getContent方法得到邮件内容,然后将返回对象的类型转换成String输出给显示软件即可。如果邮件类型为"multipart/*",表示邮件内容是一个复合类型,此时需将Message.getContent方法复合的对象转换成Multipart。

3、调用Multipart对象的getCount方法检测Multipart对象中封装了多少个BodyPart对象,并通过for循环逐一取出Multipart对象中的每个BodyPart对象进行处理。

4、在处理每个BodyPart对象时,首先调用BodyPart对象的getContentType方法得到它的MIME类型,然后根据MIME类型作出如下三种情况的处理:

  当MIME类型为"text/*"时,表示BodyPart对象中保存的是纯文本数据,如上图中的"text/plain",此时第一BodyPart对象的getContent方法并将返回的对象转换成String输出给显示软件显示即可。

  当MIME类型表示的是图片、声音或者是附件等二进制数据时,如上图中的"image/gif"时,此时应调用BodyPart对象的getDataHandler方法得到了封装了数据的DataHanlder对象,然后调用DataHandler对象的getInputStream方法获得与数据相关联的InputStream对象,通过这个InputStream对象中即可获得原始的二进制数据内容。

  当MIME类型为"multipart/mixed"时,表示BodyPart对象中保存的是一个复合MIME消息,此时应调用BodyPart对象的getContent方法得到封装复合MIME消息的对象并将它转换成Multipart类型,接着重复第3和第4个步骤操作对Multipart对象进行递归调用。

下面来编写一个接收并解析带有附件的程序

POP3Help.java

 package mail;

 import java.util.Properties;

 import javax.mail.Folder;
import javax.mail.Session;
import javax.mail.Store; public class POP3Help {
public static Folder getFolder(String host, String username, String password) {
Properties prop = new Properties();
prop.setProperty("mail.store.protocol", "pop3");
prop.setProperty("mail.pop3.host", host); Session mailSession = Session.getDefaultInstance(prop, null);
mailSession.setDebug(false); try {
Store store = mailSession.getStore("pop3");
store.connect(host, username, password);
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_WRITE);
return folder;
} catch (Exception e) {
e.printStackTrace();
} return null;
}
}

该类用来连接和登录POP3服务器,并返回代表邮件夹的Folder对象

index.html

 <html>
<head>
<title>login.html</title>
</head>
<body>
<form action="login.jsp" method="post">
主机名:<input name="host" type="text"><br/>
用户名:<input name="username" type="text"><br/>
密码:<input name="password" type="password"><br/>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>

登录页面,需要用户填写邮件服务器的主机名,用户名和密码

login.jsp

 <%@ page import="javax.mail.*,mail.*"
contentType="text/html;charset=GB2312" %>
<%
String host = request.getParameter("host");
String username = request.getParameter("username");
String password = request.getParameter("password");
String from = "";
String subject = "";
Folder folder = POP3Help.getFolder(host,username,password);
session.setAttribute("folder",folder);
Message [] messages = folder.getMessages(); for(int i=0;i<messages.length;i++)
{
try
{
from = messages[i].getFrom()[0].toString();
subject = messages[i].getSubject();
out.print(i + 1);
%>
发件人地址:<%=from %> 邮件主题:<%=subject %>
<a href="displayMsg.jsp?msgnum=<%=i+1%>">查看邮件</a><br/>
<%
}
catch(Exception e){}
}
%>

获取邮件夹中的所有邮件

displayMsg.jsp

 <frameset rows="25%,*">
<frame src="/mailDemo/DisplayHead?msgnum=<%=request.getParameter("msgnum")%>" scrolling="no">
<frame src="/mailDemo/DisplayContent?msgnum=<%=request.getParameter("msgnum")%>" scrolling="no">
</frameset>

用于展示邮件的信息

DisplayHead.java

 package mail;

 import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat; import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.internet.MimeUtility;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @SuppressWarnings("serial")
public class DisplayHead extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=gb2312");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
int msgnum = Integer.parseInt(request.getParameter("msgnum"));
Folder folder = (Folder) session.getAttribute("folder"); try {
Message msg = folder.getMessage(msgnum);
String from = msg.getFrom()[0].toString();
String subject = msg.getSubject();
String sendDate = DateFormat.getInstance().format(msg.getSentDate()); out.println("邮件主题:" + subject + "<br/>");
out.println("发件人:" + from + "<br/>");
out.println("发送日期:" + sendDate + "<br/><br/>"); System.out.println("contentType:" + msg.getContentType()); // 如果该邮件是组合型"multipart/*"则可能包含附件等
if (msg.isMimeType("multipart/*")) {
Multipart mp = (Multipart) msg.getContent(); for (int i = 0; i < mp.getCount(); i++) {
BodyPart bp = mp.getBodyPart(i); // 如果该BodyPart对象包含附件,则应该解析出来
if (bp.getDisposition() != null) {
String filename = bp.getFileName();
System.out.println("filename:" + filename); if (filename.startsWith("=?")) {
// 把文件名编码成符合RFC822规范
filename = MimeUtility.decodeText(filename);
} // 生成打开附件的超链接
out.print("附件:");
out.print("<a href=HandleAttach?msgnum=" + msgnum + "&&bodynum=" + i + "&&filename=" + filename
+ ">" + filename + "</a><br/>");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

用于显示邮件头内容

DisplayContent.java

 package mail;

 import java.io.IOException;

 import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @SuppressWarnings("serial")
public class DisplayContent extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletOutputStream sos = response.getOutputStream();
HttpSession session = request.getSession();
int msgnum = Integer.parseInt(request.getParameter("msgnum"));
Folder folder = (Folder) session.getAttribute("folder"); try {
Message msg = folder.getMessage(msgnum);
// 邮件类型不是mixed时,表示邮件中不包含附件,直接输出邮件内容
if (!msg.isMimeType("multipart/mixed")) {
response.setContentType("message/rfc822");
msg.writeTo(sos);
} else {
// 查找并输出邮件中的邮件正文
Multipart mp = (Multipart) msg.getContent();
int bodynum = mp.getCount();
for (int i = 0; i < bodynum; i++) {
BodyPart bp = mp.getBodyPart(i);
/*
* MIME消息头中不包含disposition字段, 并且MIME消息类型不为mixed时,
* 表示当前获得的MIME消息为邮件正文
*/
if (!bp.isMimeType("multipart/mixed") && bp.getDisposition() == null) {
response.setContentType("message/rfc822");
bp.writeTo(sos);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

用于显示邮件正文

HandleAttact.java

 package mail;

 import java.io.IOException;
import java.io.InputStream;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @SuppressWarnings("serial")
public class HandleAttach extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
HttpSession session = request.getSession();
ServletOutputStream out = response.getOutputStream(); int msgnum = Integer.parseInt(request.getParameter("msgnum"));
int bodynum = Integer.parseInt(request.getParameter("bodynum"));
String filename = request.getParameter("filename");
Folder folder = (Folder) session.getAttribute("folder"); try {
Message msg = folder.getMessage(msgnum); // 将消息头类型设置为附件类型
response.setHeader("Content-Disposition", "attachment;filename=" + filename); Multipart multi = (Multipart) msg.getContent();
BodyPart bodyPart = multi.getBodyPart(bodynum); InputStream is = bodyPart.getInputStream();
int c = 0;
while ((c = is.read()) != -1) {
out.write(c);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

用于处理附件

web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>mailDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list> <servlet>
<servlet-name>DisplayHead</servlet-name>
<servlet-class>mail.DisplayHead</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayHead</servlet-name>
<url-pattern>/DisplayHead</url-pattern>
</servlet-mapping> <servlet>
<servlet-name>DisplayContent</servlet-name>
<servlet-class>mail.DisplayContent</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayContent</servlet-name>
<url-pattern>/DisplayContent</url-pattern>
</servlet-mapping> <servlet>
<servlet-name>HandleAttach</servlet-name>
<servlet-class>mail.HandleAttach</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HandleAttach</servlet-name>
<url-pattern>/HandleAttach</url-pattern>
</servlet-mapping>
</web-app>

首先启动tomcat服务器,然后在浏览器中输入http://localhost:8080/mailDemo/index.html

输入用户名跟密码(这里需要填写授权码,什么是授权码,它又是如何设置?

列出了邮件夹中所有的邮件

点击查看邮件链接

点击附件后面的文件名称即可下载对应附件。

JavaMail入门第五篇 解析邮件的更多相关文章

  1. JavaMail入门第四篇 接收邮件

    上一篇JavaMail入门第三篇 发送邮件中,我们学会了如何用JavaMail API提供的Transport类发送邮件,同样,JavaMail API中也提供了一些专门的类来对邮件的接收进行相关的操 ...

  2. JavaMail入门第三篇 发送邮件

    JavaMail API中定义了一个java.mail.Transport类,它专门用于执行邮件发送任务,这个类的实例对象封装了某种邮件发送协议的底层实施细节,应用程序调用这个类中的方法就可以把Mes ...

  3. Android JNI入门第五篇——基本数据类型使用

    前面讲到了java和native数据类型,这里就开始做一下使用: 第一步:新建工程 第二部:书写 java方法: public class NativeMethod { static { System ...

  4. Hadoop入门第五篇:Hive简介以及部署

    标签(空格分隔): Hadoop Hive hwi 1.Hive简介   之前我一直在Maxcompute上进行大数据开发,所以对数仓这块还算比较了解,在接受Hive的时候基本上没什么大的障碍.所以, ...

  5. Visualforce入门第五篇_2017.3.1

    Visualforce添加过滤器,实现数据的筛选 参考原文:https://trailhead.salesforce.com/modules/visualforce_fundamentals/unit ...

  6. java入门第五步之数据库项目实战【转】

    在真正进入代码编写前些进行一些工具的准备: 1.保证有一个可用的数据库,这里我用sql server 2000为例,2.拥有一个ide,如ecelise或myeclipse等,这里我使用的是myecl ...

  7. 大数据入门第五天——离线计算之hadoop(上)概述与集群安装

    一.概述 根据之前的凡技术必登其官网的原则,我们当然先得找到它的官网:http://hadoop.apache.org/ 1.什么是hadoop 先看官网介绍: The Apache™ Hadoop® ...

  8. Android JNI入门第六篇——C调用Java

    本篇将介绍在JNI编程中C调用Java实现. 源码下载地址:http://download.csdn.net/detail/xyz_lmn/4868265 关键代码: java: public cla ...

  9. # hadoop入门第六篇:Hive实例

    前言   前面已经讲了如何部署在hadoop集群上部署hive,现在我们就做一个很小的实例去熟悉HIVE QL.使用的数据是视频播放数据包括视频编码,播放设备编码,用户账号编码等,我们在这个数据基础上 ...

随机推荐

  1. windows下使用vim+ctags+taglist

    最近在公司的同事指导下,学会使用这个东西编写代码,效率提高了不少.所以记录下来,方便大家使用. 1. 下载gvim74.exe文件,并安装.注意一般安装的路径中不要存在空格 2. 下载taglist_ ...

  2. Android 中ViewPagerIndicator的使用

    1.https://github.com/JakeWharton/Android-ViewPagerIndicator 2.http://blog.csdn.net/xiaanming/article ...

  3. 关于Python的web框架

    uliwebhttp://git.oschina.net/limodou/uliweb uliweb 吸取了其他框架的经验,集成了orm.总的来说一般.这个安装后有个exe文件,命令行工具.不绿色.个 ...

  4. 免费WebService服务

    国内手机号码归属地查询:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx 中国股票及时行情数据:http://webservi ...

  5. ux.form.field.TreePicker 扩展,修复火狐不能展开bug

    /** * A Picker field that contains a tree panel on its popup, enabling selection of tree nodes. * 动态 ...

  6. pdf嵌入字体

    论文提交时,要求所有的字体都是嵌入的,为这个问题折腾了很久,发现了一个很好的答案,记一下: http://stackoverflow.com/questions/4231656/how-do-i-em ...

  7. 【Android】Activity生命周期(亲测)

    测试手机:Nexus 5   系统:4.4 一.测试 测试代码: package com.example.androidalarm; import android.app.Activity; impo ...

  8. Objective-C之类和对象

    http://www.cnblogs.com/kenshincui/p/3861302.html

  9. Marven笔记贴

    本篇只是作为自学Marven的笔记贴,基本上都是网上的各种资料的汇总,方便自己和需要的人,不用一个个去找浪费时间了. 什么是Marven You want to start with a projec ...

  10. Linux 时钟与计时器

    对 Linux 系统来说,时钟和计时器是两个十分重要的概念.时钟反应的是绝对时间,也可认为是实时时间.计时器反应的则是相对时间,即相对于系统启动后的计时.操作系统内核需要管理运行时间(uptime)和 ...