JavaMail实现收发邮件——(二)接收邮件

2018-10-09 08:35:00     

一、准备工作

1.jar包准备,你可以从 Java 网站下载最新版本的jar包,也可以使用本站提供的下载链接:

2.QQ 邮件服务器,你需要在登录QQ邮箱后台在"设置"=》账号中开启上面两个:(授权码在下面代码要使用)

二、JSP页面

a标签进入邮箱主页,查询所有邮箱。

<a href="${pageContext.request.contextPath}/POP3">进入邮箱</a>

三、Servlet代码

javamail接受邮件的核心API:
  1. Store类:用于执行邮件的接收任务,在程序中调用这个类中的方法可以获取邮箱中的各个邮件夹的信息
  • 客户端程序接收邮件时,只需要使用邮件接收 API 得到Store对象,然后调用Store对象的接收方法,就可以从指定的POP3服务器获得邮件数据,并把这些邮件数据封装到表示邮件的Message对象中。
  • Folder类:JavaMail使用Folder对象表示邮件夹
  • 通过Folder对象的方法可以获取邮件夹中的所有邮件信息

获取邮件夹中所有的邮件:

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.sun.mail.util.MailSSLSocketFactory;

@WebServlet("/POP3")
public class POP3 extends HttpServlet {
private static final long serialVersionUID = 1L;
public POP3() {
	super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	PrintWriter out = response.getWriter();
	HttpSession session = request.getSession();
	// 定义连接POP3服务器的属性信息
	String host = "pop.qq.com";
	String user = "1455973223@qq.com";
	String from = "";
	// QQ邮箱的SMTP的授权码
	String pwd = "xxxxxxxx";
	Folder folder;
	try {
		folder = POP3Help.getFolder(host, user, pwd);
		session.setAttribute("folder", folder);
		// 得到收件箱中的所有邮件,并解析
		Message[] messages = folder.getMessages();
		// 打印收件箱邮件部分信息
		out.println("邮件总数: " + folder.getMessageCount() + "<br/>");
		int length = messages.length;
		for (int i = 0; i < length; i++) {
			from = MimeUtility.decodeText(messages[i].getFrom()[0].toString());
			InternetAddress ia = new InternetAddress(from);
			out.println("发件人地址:" + (ia.getPersonal() + '(' + ia.getAddress() + ')' + "<br/>"));
			out.println("邮件主题:" + (messages[i].getSubject() + "<br/>"));
			out.println("邮件发送时间:"
			+ (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(messages[i].getSentDate()) + "<br/>"));
			out.println("邮件大小:" + (messages[i].getSize() * 1024 + "kb" + "<br/>"));
			i=i+1;
			out.println("<a href=\"/springTest/Display?msgnum=" + i + "\">查看邮件</a><br/>");
			i=i-1;
			out.println(
					" -----------------------------------------------------------");
			out.println("<br/><br/>");
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	doGet(request, response);
}

public static Folder getFolder(String host, String username, String password) throws Exception {
	Properties prop = new Properties();
	prop.setProperty("mail.store.protocol", "pop3");
	prop.setProperty("mail.pop3.host", host);
	// QQ邮箱,设置SSL加密(必须要加密)
	MailSSLSocketFactory sf = new MailSSLSocketFactory();
	sf.setTrustAllHosts(true);
	prop.put("mail.pop3.ssl.enable", "true");
	prop.put("mail.pop3.ssl.socketFactory", sf);
	// 获取默认session对象
	Session mailSession = Session.getDefaultInstance(prop, null);
	mailSession.setDebug(false);
	try {
		//获取store对象
		Store store = mailSession.getStore("pop3");
		// 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;
  }
}

效果如下:


用于展示单个邮件的详细信息:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpSession;

@WebServlet("/Display")
public class Display extends HttpServlet {
private static final long serialVersionUID = 1L;

public Display() {
	super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	response.setContentType("text/html;charset=UTF-8");
	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);
		// 解决Folder is not Open的问题
		if (!msg.getFolder().isOpen()) // 判断是否open
			msg.getFolder().open(Folder.READ_WRITE); // 如果close,就重新open
		//获得发件人地址
		String from = MimeUtility.decodeText(msg.getFrom()[0].toString());
		//获得邮件主题
		String subject = msg.getSubject();
		//获取邮件发送时间
		String sendDate = DateFormat.getInstance().format(msg.getSentDate());
		out.println("发件人:" + from + "<br/><br/>");
		out.println("邮件主题:" + subject + "<br/><br/>");
		out.println("发送日期:" + sendDate + "<br/><br/>");
		//判断是否有附件
		boolean isContainerAttachment = isContainAttachment(msg);
		if (isContainerAttachment) {
			//在E盘创建mail目录用于保存附件,返回附件名
			out.println("附件:" + saveAttachment(msg, "D:\\AllTest\\mail\\")+"<br/><br/>");
		}
		StringBuffer content = new StringBuffer(30);
		getMailTextContent(msg, content);
		out.println("邮件正文:" + content+"<br/><br/>");
	} catch (
	Exception e) {
		e.printStackTrace();
	}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	doGet(request, response);
}
/**
 * 判断是否包含附件
 */
public static boolean isContainAttachment(Part part) throws MessagingException, IOException {
	boolean flag = false;
	if (part.isMimeType("multipart/*")) {
		MimeMultipart multipart = (MimeMultipart) part.getContent();
		int partCount = multipart.getCount();
		for (int i = 0; i < partCount; i++) {
			BodyPart bodyPart = multipart.getBodyPart(i);
			String disp = bodyPart.getDisposition();
			if (disp!=null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))){
				flag = true;
			} else if (bodyPart.isMimeType("multipart/*")) {
				flag = isContainAttachment(bodyPart);
			} else {
				String contentType = bodyPart.getContentType();
				if (contentType.indexOf("application") != -1) {
					flag = true;
				}

				if (contentType.indexOf("name") != -1) {
					flag = true;
				}
			}

			if (flag)
				break;
		}
	} else if (part.isMimeType("message/rfc822")) {
		flag = isContainAttachment((Part) part.getContent());
	}
	return flag;
}
/**
 * 保存附件
 */
public static String saveAttachment(Part part, String destDir)
		throws UnsupportedEncodingException, MessagingException, FileNotFoundException, IOException {
	BodyPart bodyPart=null;
	if (part.isMimeType("multipart/*")) {
		Multipart multipart = (Multipart) part.getContent(); // 复杂体邮件
		// 复杂体邮件包含多个邮件体
		int partCount = multipart.getCount();
		for (int i = 0; i < partCount; i++) {
			// 获得复杂体邮件中其中一个邮件体
			bodyPart = multipart.getBodyPart(i);
			// 某一个邮件体也有可能是由多个邮件体组成的复杂体
			String disp = bodyPart.getDisposition();
			if (disp!=null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {
				InputStream is = bodyPart.getInputStream();
				saveFile(is, destDir, decodeText(bodyPart.getFileName()));
			} else if (bodyPart.isMimeType("multipart/*")) {
				saveAttachment(bodyPart, destDir);
			} else {
				String contentType = bodyPart.getContentType();
				if (contentType.indexOf("name") != -1 || contentType.indexOf("application") != -1) {
					saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName()));
				}
			}
		}
	} else if (part.isMimeType("message/rfc822")) {
		saveAttachment((Part) part.getContent(), destDir);
	}
	return decodeText(bodyPart.getFileName());
}
/**
 * 读取输入流中的数据保存至指定目录
 */
private static void saveFile(InputStream is, String destDir, String fileName)
		throws FileNotFoundException, IOException {
	BufferedInputStream bis = new BufferedInputStream(is);
	BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(destDir + fileName)));
	int len = -1;
	while ((len = bis.read()) != -1) {
		bos.write(len);
		bos.flush();
	}
	bos.close();
	bis.close();
}
/**
 * 文本解码
 */
public static String decodeText(String encodeText) throws UnsupportedEncodingException {
	if (encodeText == null || "".equals(encodeText)) {
		return "";
	} else {
		return MimeUtility.decodeText(encodeText);
	}
}
/**
 * 获得邮件文本内容
 */
public static void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {
	// 如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
	boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
	if (part.isMimeType("text/*") && !isContainTextAttach) {
		content.append(part.getContent().toString());
	} else if (part.isMimeType("message/rfc822")) {
		getMailTextContent((Part) part.getContent(), content);
	} else if (part.isMimeType("multipart/*")) {
		Multipart multipart = (Multipart) part.getContent();
		int partCount = multipart.getCount();
		for (int i = 0; i < partCount; i++) {
			BodyPart bodyPart = multipart.getBodyPart(i);
			getMailTextContent(bodyPart, content);
		}
	}
  }
}

效果如下图:

四、总结

1.调用Message对象的getFromgetSubject等方法,可以得到邮件的发件人和主题等信息,调用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对象进行递归调用。

ps:本篇博客源码下载链接:https://pan.baidu.com/s/10kiOqSqEfoKXRkWJPi6HWg 密码:zpd9
JavaMail实现收发邮件——(一)发送邮件

一、准备工作1.jar包准备,你可以从 Java 网站下载最新版本的jar包,也可以使用本站提供的下载链接:JavaMail mail.jar 1.4.5JAF(版本 1.1.1) activation.jar2.QQ 邮件服务器,你需要在登录QQ邮箱后台在"设置"=》账号中开启上面两个:(授权码在下面代码要使用)二、分析QQ邮箱发件人: 发件人的QQ邮箱,只能是一个收件人: 收件人的邮箱,可以有多个主题: 可写可不写,如果不写容易被QQ邮件服务器当作垃圾邮件处理正文: 邮件的主体内容附件: 就是文件,图片之类的东西抄送: 同时将这一封邮件发送给其他人,抄送人可见其他抄送人的邮箱密送: 同时将这一封邮件发送给其他人,密送人看不到其他密送人的邮箱三、jsp页面form表单采用post方式提交。收件人邮箱这里设置两个,设置其中一个必填,且name属性要一样。<form method="post" action="${pageContext.

Maven项目管理工具

一、分析思考企业大型项目一般是由各个小项目(A,B等小项目)依赖形成的。假设A项目要依赖B项目中的某些类,我们就要去网上下载相关的jar包,分别放到A项目中和B项目中。此时就存在了一些问题:如果jar包多,且A,B项目都要用这些jar包。大型项目就会变得笨重,繁琐,占用内存莫名其妙的就变大了。所以,我们用Maven来管理这些jar包。二、什么是Maven不说什么大白话,我们说通俗易懂的:基于Java平台的项目构建,依赖管理和项目信息管理依赖管理就是使用Maven来管理项目中的jar包,Maven管理的方式就是“自动下载项目所需要的jar包,统一管理jar包之间的依赖关系”三、安装Maven这里不详细讲解安装步骤,跟安装jdk环境类似,给出链接:maven的安装教程和配置桌面上安装配置好Maven后还需要在Eclipse上安装Maven,给出链接:Eclipse上安装Maven四、Maven的简单应用 先创建一个Maven的简单应用,详细介绍,给出链接:Eclipse创建Maven项目 接下来重点关注pom.xml文件五、pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.

 发表评论