Java 接收邮件

概要:

POP3(Post Office Protocol version 3)是一种常用的网络协议,POP3是邮局通信协定的第三个版本,是互联网上的一种通信协定,主要功能是用来传送电子邮件,从远程服务器的信箱里收取电子邮件。例如,当我们寄信给另外一个人时,对方当时多半不会在线上,所以邮件服务器必须为收信者保存这封信,直到收信者来检查这封信件。当收信人收信的时候,必须通过POP3通信协定,才能取得邮件。本实例将演示如何利用POP3接收邮件。

| |目录

技术要点

  • 用Java Mail API以POP3协议接收邮件的技术在点如下:

  • Store类:该类代表了存储邮件的邮件服务器,用于存储和获取消息。

  • Folder类:该类用于描述邮件的分级组织,如收件箱。通过Store的getFolder()方法可以创建一个Folder对象。

  • Folder的open方法打开此Folder。此方法仅对可以包含Message并处于关闭状态的Folder有效。

  • Folder的close方法关闭此Folder,此方法只对已打开的Folder对象有效。

  • Folder的getMessages(int start,int end)方法获取从start到end消息编号范围内(包括start和end)Message对象。值得注意的是,消息编号从1而不是从0开始。

  • Folder的getNewMessageCount方法获取此Folder中消息的总数,即新邮件的数量。

  • Folder的getUnreadMessageCount方法获取此Folder中未读消息的总数,即未读邮件的数量。

  • MimeMessage的getFrom方法获得邮件的发件人地址列表。返回值类型为InternetAddress数组。

  • MimeMessage的getRecipients方法获得邮件的收件人地址列表。返回值类型为InternetAddress数组。

  • InternetAddress的getAddress方法获得邮件地址,InternetAddress的getPersonal方法获得邮件地址的个人信息。

  • MimeMessage的getSubject方法获得邮件的主题。

  • MimeMessage的getSentDate方法获得邮件的发送日期。

  • MimeMessage的getMessageID方法获得邮件的ID(表示邮件)。

  • 通过MimeMessage的getContent方法获得邮件的内容,如果邮件是MIME邮件,那么得到的是一个Multipart的对象;如果是普通的文本邮件,那么得到的是BodyPart对象。当BodyPart的MimeType类型为"multipart/*"时,表示它是一个Multipart。

  • 当一个BodyPart的disposition属性等于Part.ATTACHMENT或者Part.INLINE常量时,表示它带有附件。

代码实现

Receive_Mail.java 处理邮件接收信息

package net.xsoftlab.baike;
import java.io.*;
import java.util.Date;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
public class Receive_Mail {
	private R_MailInfo R_Info; // 收邮件的参数配置
	private Store store; // 与邮件服务器连接后得到的邮箱
	private Folder folder; // 收件箱
	private Message[] mess; // 收件箱中的邮件消息
	private Message C_Message; // 当前正在处理的邮件消息
	private String C_FileName;// 当前正在处理的文件名称
	private Session session;// 创建与邮件服务器的会话
	String file_path = "";// 定义保存后的文本文件的地址
	public Receive_Mail(R_MailInfo R_Info) {// 构造方法
		this.R_Info = R_Info;
	}
	/** 收邮件 */
	public void M_receiveMail() throws Exception {
		if (this.R_Info == null) {
			throw new Exception("请载入接收邮件的参数!");
		}
		if (this.connectToServer()) { // 连接到服务器
			if (this.openInBoxFolder()) {// 打开收件箱
				this.getAllMail();// 获取所有邮件
				this.closeConnection();
			} else {
				throw new Exception("*****进入收件夹失败!*****");
			}
		} else {
			throw new Exception("*****邮件服务器连接失败!*****");
		}
	}
	/** 登陆邮件服务器 */
	private boolean connectToServer() {
		MailAttorney authenticator = null;
		if (this.R_Info.isIsvalidate()) {// 判断是否需要身份认证
			// 如果需要身份认证,则创建一个密码验证器
			authenticator = new MailAttorney(this.R_Info.getUserName(),
					this.R_Info.getPassword());
		}
		session = Session.getInstance(this.R_Info.getProperties(),
				authenticator);// 创建session
		try {
			this.store = session.getStore(this.R_Info.getProtocal());// 创建store
		} catch (NoSuchProviderException e) {
			System.out.println("连接服务器失败!");
			return false;
		}
		System.out.println("正在连接服务器,请稍候……");
		try {
			this.store.connect();// 建立连接
		} catch (MessagingException e) {
			System.out.println("连接服务器失败!");
			return false;
		}
		System.out.println("连接服务器成功");
		return true;
	}
	/** 打开收件夹 */
	private boolean openInBoxFolder() {
		try {
			this.folder = store.getFolder("INBOX");
			folder.open(Folder.READ_WRITE); // 设置文件夹的状态为可读写
			Message[] massge = folder.getMessages();// 获得此文件夹中的所有信息
			for (int i = 0; i < massge.length; i++) {
				massge[i].setFlag(Flags.Flag.DELETED, true);// 标记此邮件的flag标志对象的DELETED位为true,可以在读完邮件后直接删除该附件,
				try {
					handle_Multipart(massge[i]);
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out
						.println("********************************************************");
			}
			return true;
		} catch (MessagingException e) {
			System.err.println("收件夹信息获取失败!");
		}
		return false;
	}
	private void handle_Multipart(Message massge) {
		try {
			handle(massge);
			String disposition;
			BodyPart part;
			Multipart mp = (Multipart) massge.getContent();
			int mpCount = mp.getCount();
			// Miltipart的数量,用于除了多个part,比如多个附件
			for (int m = 0; m < mpCount; m++) {
				part = mp.getBodyPart(m);
				disposition = part.getDisposition();
				if (disposition != null && disposition.equals(Part.ATTACHMENT)) {
					M_saveAnnex(part);
				} else {
					System.out.println(part.getContent());
				}
			}
		} catch (Exception e) {
		}
	}
	private void M_saveAnnex(BodyPart part) {// 保存附件
		String fileName;
		try {
			fileName = getFileName(part);// 获得附件的名称
			System.out.println("有附件: " + fileName);
			InputStream in = part.getInputStream();
			FileOutputStream writer = new FileOutputStream(new File(
					"F:\attachments\" + fileName));// 创建文件输出流
			System.out.println("保存路径为: " + "F:\attachments\" + fileName);
			byte[] b = new byte[255];
			int length = 0;
			while ((length = in.read(b)) != -1) {
				writer.write(b);// 将流写入指定的文件
			}
			writer.close();
			in.close();
		} catch (Exception e) {
		}
	}
	private void handle(Message massge) throws Exception {
		System.out.println("邮件主题:" + massge.getSubject());
		System.out.println("发送日期:" + massge.getSentDate());
		System.out.println("发送地址:" + massge.getFrom()[0]);
	}
	/** 断开与邮件服务器的连接 */
	private boolean closeConnection() {
		try {
			if (this.folder.isOpen()) {
				this.folder.close(true);
			}
			this.store.close();
			System.out.println("成功关闭与邮件服务器的连接!");
			return true;
		} catch (Exception e) {
			System.out.println("关闭和邮件服务器之间连接时出错!");
		}
		return false;
	}
	/** 获取mess中的所有邮件 */
	private void getAllMail() throws MessagingException {
		// 从邮件文件夹获取邮件信息
		this.mess = this.folder.getMessages();
		System.out.println("总的邮件数目:" + mess.length);
		System.out.println("新邮件数目:" + this.getNewMessageCount());
		System.out.println("未读邮件数目:" + this.getUnreadMessageCount());
		// 将要下载的邮件的数量。
		int mailArrayLength = this.getMessageCount();
		System.out.println("一共有邮件" + mailArrayLength + "封");
		int successCounter = 0;
		int errorCounter = 0;
		for (int index = 0; index < mailArrayLength; index++) {
			try {
				this.C_Message = (mess[index]); // 根据消息编号获取消息
				System.out.println("正在获取第" + (index + 1) + "封邮件......");
				M_showMail(this.C_Message);// 显示该消息的基本信息
				getMail(); // 获取当前message
				System.out.println("成功获取第" + (index + 1) + "封邮件");
				successCounter++;
			} catch (Throwable e) {
				errorCounter++;
				System.err.println("下载第" + (index + 1) + "封邮件时出错");
			}
		}
		System.out.println("------------------");
		System.out.println("成功下载了" + successCounter + "封邮件");
		System.out.println("失败下载了" + errorCounter + "封邮件");
		System.out.println("------------------");
	}
	/** 显示邮件的基本信息 */
	private void M_showMail(Message message) throws Exception {
		System.out.println("发件人:" + this.getFrom());
		System.out.println("收件人:" + this.getTOAddress());
		System.out.println("抄送人:" + this.getCCAddress());
		System.out.println("密送人:" + this.getBCCAddress());
		System.out.println("主 题:" + this.getSubject());
		System.out.println("日 期::" + this.getSentDate());
		System.out.print("是新邮件? ");
		System.out.println(this.isNew() ? "是" : "不是");
		System.out.print("要求回执?");
		System.out.println(this.getReplySign() ? "是" : "不是");
		System.out.print("包含附件?");
		System.out.println(this.isContainAttach() ? "包含" : "不包含");
		System.out.println("------------------------------");
	}
	/**
	 * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
	 */
	private String getTOAddress() throws Exception {
		return getMailAddress("TO", this.C_Message);
	}
	private String getCCAddress() throws Exception {
		return getMailAddress("CC", this.C_Message);
	}
	private String getBCCAddress() throws Exception {
		return getMailAddress("BCC", this.C_Message);
	}
	/**
	 * 获得邮件地址
	 * 
	 * @param type
	 *            类型,如收件人、抄送人、密送人
	 * @param mimeMessage
	 *            邮件消息
	 */
	private String getMailAddress(String type, Message mimeMessage)
			throws Exception {
		String mailaddr = "";
		String addtype = type.toUpperCase();
		InternetAddress[] address = null;
		if (addtype.equals("TO") || addtype.equals("CC")
				|| addtype.equals("BCC")) {
			if (addtype.equals("TO")) {
				address = (InternetAddress[]) mimeMessage
						.getRecipients(Message.RecipientType.TO);
			} else if (addtype.equals("CC")) {
				address = (InternetAddress[]) mimeMessage
						.getRecipients(Message.RecipientType.CC);
			} else {
				address = (InternetAddress[]) mimeMessage
						.getRecipients(Message.RecipientType.BCC);
			}
			if (address != null) {
				for (int i = 0; i < address.length; i++) {
					// 先获取邮件地址
					String email = address[i].getAddress();
					if (email == null) {
						email = "";
					} else {
						email = MimeUtility.decodeText(email);
					}
					// 再取得个人描述信息
					String personal = address[i].getPersonal();
					if (personal == null) {
						personal = "";
					} else {
						personal = MimeUtility.decodeText(personal);
					}
					// 将个人描述信息与邮件地址连起来
					String compositeto = personal + "<" + email + ">";
					// 多个地址时,用逗号分开
					mailaddr += "," + compositeto;
				}
				mailaddr = mailaddr.substring(1);
			}
		} else {
			throw new Exception("错误的地址类型!!");
		}
		return mailaddr;
	}
	/** 获得发件人的地址和姓名 */
	private String getFrom() throws Exception {
		return getFrom(this.C_Message);
	}
	private String getFrom(Message mimeMessage) throws Exception {
		InternetAddress[] address = (InternetAddress[]) mimeMessage.getFrom();
		// 获得发件人的邮箱
		String from = address[0].getAddress();
		if (from == null) {
			from = "";
		}
		// 获得发件人的描述信息
		String personal = address[0].getPersonal();
		if (personal == null) {
			personal = "";
		}
		// 拼成发件人完整信息
		String fromaddr = personal + "<" + from + ">";
		return fromaddr;
	}
	/** 获取mess中message的数量 */
	private int getMessageCount() {
		return this.mess.length;
	}
	/** 获得收件箱中新邮件的数量 */
	private int getNewMessageCount() throws MessagingException {
		return this.folder.getNewMessageCount();
	}
	/** 获得收件箱中未读邮件的数量 */
	private int getUnreadMessageCount() throws MessagingException {
		return this.folder.getUnreadMessageCount();
	}
	/** 获得邮件主题 */
	private String getSubject() throws MessagingException {
		return getSubject(this.C_Message);
	}
	private String getSubject(Message mimeMessage) throws MessagingException {
		String subject = "";
		try {
			// 将邮件主题解码
			subject = MimeUtility.decodeText(mimeMessage.getSubject());
			if (subject == null) {
				subject = "";
			}
		} catch (Exception exce) {
		}
		return subject;
	}
	/** 获得邮件发送日期 */
	private Date getSentDate() throws Exception {
		return getSentDate(this.C_Message);
	}
	private Date getSentDate(Message mimeMessage) throws Exception {
		return mimeMessage.getSentDate();
	}
	/** 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false" */
	private boolean getReplySign() throws MessagingException {
		return getReplySign(this.C_Message);
	}
	private boolean getReplySign(Message mimeMessage) throws MessagingException {
		boolean replysign = false;
		String needreply[] = mimeMessage
				.getHeader("Disposition-Notification-To");
		if (needreply != null) {
			replysign = true;
		}
		return replysign;
	}
	private String getMessageId(Message mimeMessage) throws MessagingException {
		return ((MimeMessage) mimeMessage).getMessageID();
	}
	/** 判断此邮件是否已读,如果未读返回返回false,反之返回true */
	private boolean isNew() throws MessagingException {
		return isNew(this.C_Message);
	}
	private boolean isNew(Message mimeMessage) throws MessagingException {
		boolean isnew = false;
		Flags flags = mimeMessage.getFlags();
		Flags.Flag[] flag = flags.getSystemFlags();
		for (int i = 0; i < flag.length; i++) {
			if (flag[i] == Flags.Flag.SEEN) {
				isnew = true;
				break;
			}
		}
		return isnew;
	}
	/** 判断此邮件是否包含附件 */
	private boolean isContainAttach() throws Exception {
		return isContainAttach(this.C_Message);
	}
	private boolean isContainAttach(Part part) throws Exception {
		boolean attachflag = false;
		if (part.isMimeType("multipart/*")) {
			// 如果邮件体包含多部分
			Multipart mp = (Multipart) part.getContent();
			// 遍历每部分
			for (int i = 0; i < mp.getCount(); i++) {
				// 获得每部分的主体
				BodyPart bodyPart = mp.getBodyPart(i);
				String disposition = bodyPart.getDisposition();
				if ((disposition != null)
						&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
								.equals(Part.INLINE)))) {
					attachflag = true;
				} else if (bodyPart.isMimeType("multipart/*")) {
					attachflag = isContainAttach((Part) bodyPart);
				} else {
					String contype = bodyPart.getContentType();
					if (contype.toLowerCase().indexOf("application") != -1) {
						attachflag = true;
					}
					if (contype.toLowerCase().indexOf("name") != -1) {
						attachflag = true;
					}
				}
			}
		} else if (part.isMimeType("message/rfc822")) {
			attachflag = isContainAttach((Part) part.getContent());
		}
		return attachflag;
	}
	/** 获得当前邮件 */
	private void getMail() throws Exception {
		try {
			this.saveMessageAsFile(C_Message);
			this.parseMessage(C_Message);
		} catch (Exception e) {
			throw new Exception("未知错误");
		}
	}
	/** 保存邮件源文件 */
	private void saveMessageAsFile(Message message) {
		try {
			// 将邮件的ID中尖括号中的部分做为邮件的文件名
			String oriFileName = getInfoBetweenBrackets(this.getMessageId(
					message).toString());
			// 设置文件后缀名。若是附件则设法取得其文件后缀名作为将要保存文件的后缀名,
			// 若是正文部分则用.htm做后缀名
			String emlName = oriFileName;
			String fileNameWidthExtension = this.R_Info.getMail_path()
					+ oriFileName + this.R_Info.getEmailFileFormat();
			File storeFile = new File(fileNameWidthExtension);
			for (int i = 0; storeFile.exists(); i++) {
				emlName = oriFileName + i;
				fileNameWidthExtension = this.R_Info.getMail_path() + emlName
						+ this.R_Info.getEmailFileFormat();
				storeFile = new File(fileNameWidthExtension);
			}
			this.C_FileName = emlName;
			System.out.println("邮件消息的存储路径: " + fileNameWidthExtension);
			// 将邮件消息的内容写入ByteArrayOutputStream流中
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			message.writeTo(baos);
			StringReader in = new StringReader(baos.toString());// 读取邮件消息流中的数据
			saveFile(fileNameWidthExtension, in); // 存储到文件
		} catch (MessagingException e) {
		} catch (Exception e) {
		}
	}
	/** 解析邮件 */
	private void parseMessage(Message message) throws IOException,
			MessagingException {
		Object content = message.getContent();
		// 处理多部分邮件
		if (content instanceof Multipart) {
			handleMultipart((Multipart) content);
		} else {
			handlePart(message);
		}
	}
	/** 解析Multipart */
	private void handleMultipart(Multipart multipart)
			throws MessagingException, IOException {
		for (int i = 0, n = multipart.getCount() - 1; i < n; i++) {
			handlePart(multipart.getBodyPart(i));
		}
	}
	/** 解析指定part,从中提取文件 */
	private void handlePart(Part part) throws MessagingException, IOException {
		String disposition = part.getDisposition();
		String contentType = part.getContentType();
		String fileNameWidthExtension = "";
		// 获得邮件的内容输入流
		InputStreamReader sbis = new InputStreamReader(part.getInputStream());
		// 没有附件的情况
		if (disposition == null) {
			if ((contentType.length() >= 10)
					&& (contentType.toLowerCase().substring(0, 10)
							.equals("text/plain"))) {
				fileNameWidthExtension = this.R_Info.getAtt_path()
						+ this.C_FileName + ".txt";
			} else if ((contentType.length() >= 9) // Check if html
					&& (contentType.toLowerCase().substring(0, 9)
							.equals("text/html"))) {
				fileNameWidthExtension = this.R_Info.getAtt_path()
						+ this.C_FileName + ".html";
			} else if ((contentType.length() >= 9) // Check if html
					&& (contentType.toLowerCase().substring(0, 9)
							.equals("image/gif"))) {
				fileNameWidthExtension = this.R_Info.getAtt_path()
						+ this.C_FileName + ".gif";
			} else if ((contentType.length() >= 11)
					&& contentType.toLowerCase().substring(0, 11)
							.equals("multipart/*")) {
				handleMultipart((Multipart) part.getContent());
			} else {
				fileNameWidthExtension = this.R_Info.getAtt_path()
						+ this.C_FileName + ".txt";
			}
			// 存储内容文件
			file_path = this.R_Info.getAtt_path() + this.C_FileName + ".txt";
			file_path = file_path.replace("\", "");
			System.out.println("保存邮件内容到:" + fileNameWidthExtension);
			saveFile(fileNameWidthExtension, sbis);
			System.out.println("邮件内容为:");
			System.out.println(ReadFile() + "
");
		}
	}
	private String getFileName(Part part) throws MessagingException,// 获取附件名称
			UnsupportedEncodingException {
		String fileName = part.getFileName();
		fileName = MimeUtility.decodeText(fileName);
		String name = fileName;
		if (fileName != null) {
			int index = fileName.lastIndexOf("/");
			if (index != -1) {
				name = fileName.substring(index + 1);
			}
		}
		return name;
	}
	/**
	 * 保存文件内容
	 * 
	 * @param fileName
	 *            文件名
	 * @param input
	 *            输入流
	 * @throws IOException
	 */
	private void saveFile(String fileName, Reader input) throws IOException {
		// 为了放置文件名重名,在重名的文件名后面天上数字
		File file = new File(fileName);
		// 先取得文件名的后缀
		int lastDot = fileName.lastIndexOf(".");
		String extension = fileName.substring(lastDot);
		fileName = fileName.substring(0, lastDot);
		for (int i = 0; file.exists(); i++) {
			file = new File(fileName + i + extension); // 如果文件重名,则添加i
		}
		// 从输入流中读取数据,写入文件输出流
		FileWriter fos = new FileWriter(file);
		BufferedWriter bos = new BufferedWriter(fos);
		BufferedReader bis = new BufferedReader(input);
		int aByte;
		while ((aByte = bis.read()) != -1) {
			bos.write(aByte);
		}
		// 关闭流
		bos.flush();
		bos.close();
		bis.close();
	}
	// 读取文件内容
	public String ReadFile() {
		File file = new File(file_path);
		StringBuffer str = new StringBuffer();
		try {
			FileInputStream fi = new FileInputStream(file);
			byte[] by = new byte[(int) file.length()];
			int length = 0;
			while ((length = fi.read(by)) != -1) {
				str.append(new String(by, 0, length));
			}
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
		return str.toString();
	}
	/** 获得尖括号之间的字符 */
	private String getInfoBetweenBrackets(String str) throws Exception {
		int i, j; // 用于标识字符串中的"<"和">"的位置
		if (str == null) {
			str = "error";
			return str;
		}
		i = str.lastIndexOf("<");
		j = str.lastIndexOf(">");
		if (i != -1 && j != -1) {
			str = str.substring(i + 1, j);
		}
		return str;
	}
	public static void main(String[] args) throws Exception {
		R_MailInfo Info = new R_MailInfo();
		Info.setHost("pop.163.com");
		Info.setPort("110");
		Info.setIsvalidate(true);
		Info.setUserName("xxx@163.com");
		Info.setPassword("xxx");
		Info.setAtt_path("F:/temp/mail/");
		Info.setMail_path("F:/temp/mail/");
		Receive_Mail receiver = new Receive_Mail(Info);
		receiver.M_receiveMail();
	}
}

R_MailInfo.java设置接收邮件的基本信息

package net.xsoftlab.baike;
import java.io.File;
import java.util.Properties;
/**
 * 收邮件的基本信息
 */
public class R_MailInfo {
	// 邮件服务器的IP、端口和协议
	private String Host;
	private String Port = "110";
	private String protocal = "pop3";
	// 登陆邮件服务器的用户名和密码
	private String userName;
	private String password;
	// 保存邮件的路径
	private String att_path = "F:/temp/";
	private String mail_path = "F:/temp/";
	private String emailFileFormat = ".eml";
	// 是否需要身份验证
	private boolean Isvalidate = true;
	/** 获得邮件会话属性 */
	public Properties getProperties() {
		Properties p = new Properties();
		p.put("mail.pop3.host", this.Host);
		p.put("mail.pop3.port", this.Port);
		p.put("mail.pop3.auth", Isvalidate ? "true" : "false");
		return p;
	}
	public String getAtt_path() {
		return att_path;
	}
	public void setAtt_path(String att_path) {
		if (!att_path.endsWith(File.separator)) {
			att_path = att_path + File.separator;
		}
		this.att_path = att_path;
	}
	public String getEmailFileFormat() {
		return emailFileFormat;
	}
	public void setEmailFileFormat(String emailFileFormat) {
		if (!emailFileFormat.startsWith(".")) {
			emailFileFormat = "." + emailFileFormat;
		}
		this.emailFileFormat = emailFileFormat;
	}
	public String getHost() {
		return Host;
	}
	public void setHost(String host) {
		Host = host;
	}
	public boolean isIsvalidate() {
		return Isvalidate;
	}
	public void setIsvalidate(boolean isvalidate) {
		Isvalidate = isvalidate;
	}
	public String getMail_path() {
		return mail_path;
	}
	public void setMail_path(String mail_path) {
		if (!mail_path.endsWith(File.separator)) {
			mail_path = mail_path + File.separator;
		}
		this.mail_path = mail_path;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getPort() {
		return Port;
	}
	public void setPort(String port) {
		Port = port;
	}
	public String getProtocal() {
		return protocal;
	}
	public void setProtocal(String protocal) {
		this.protocal = protocal;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
}

MailAttorney.java 邮件身份认证器

package net.xsoftlab.baike;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
/**
 * 邮件身份认证器,在发送邮件时使用
 */
public class MailAttorney extends Authenticator {
	// 登陆发送邮件服务器的用户名和密码
	private String userName;
	private String password;
	public MailAttorney(String userName, String password) {
		this.userName = userName;
		this.password = password;
	}
	/** 覆盖父类的该方法,获得密码认证器 */
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(userName, password);
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
}

程序解读

1.MailReceiverInfo类

该类定义了收邮件时的信息,包括邮件服务器的地址、端口、协议名、是否需要身份验证、验证时的用户名和密码、附件的存储路径、邮件的存储路径、邮件文件的后缀名。

getProperties方法返回邮件会话属性,将邮件会话属性保存到一个java.util.Properties对象中。mail.pop3.host属性表示POP3服务器的地址(IP地址或者域名),mail.pop3.port属性表示POP3服务器的端口,mail.pop3.auth属性表示登录POP3服务器时是否进行身份验证。

2.MailReceiver类

(1)receiveAllMail方法用于接收所有邮件。

  • 调用connectToServer方法连接POP3服务器。

  • 调用openInBoxFolder方法打开收件箱。

  • 调用getAllMail方法获取收件箱中的所有邮件。

  • 调用closeConnection方法关闭连接。

(2)connectToServer方法连接POP3服务器。

  • 根据邮件会话属性和身份验证器创建一个Session对象。

  • 由Session对象的getStore方法创建一个Store对象,参数为POP3。

  • 调用Store的connect方法连接到POP服务器上。

(3)openInBoxFolder方法打开Store上的收件箱。

  • 调用Store的getFolder方法获得收件箱的Folder,参数为INBOX。

  • 调用Folder的open方法打开收件箱,参数为Folder.READ_ONLY,表示以只读的方式打开。

(4)closeConnection方法关闭与POP3服务器的连接。

  • 调用Folder的close方法关闭收件箱。

  • 调用Store的close方法关闭连接。

(5)getAllMail方法获得收件箱中的所有邮件。(包括已读和未读)

  • Folder的getMessages方法获得收件箱所有的邮件,返回值类型为Message[]。

  • 调用showMailBasicInfo方法显示邮件的基本信息。包括发件人信息、接收者地址、抄送者地址、密送者地址、主题、发送时间、是否为新邮件、是否需要回执、是否包含附件。

  • 调用getMail方法获取邮件。记录成功处理的邮件数和处理失败的邮件数。

(6)isContainAttach方法判断邮件是否包含附件。

  • 调用getContent方法获得Multipart对象。

  • 调用Multipart的getBodyPart方法获得邮件的BodyPart,如果BodyPart的disposition等于Part.ATTACHMENT或者Part.INLINE常量,表示它包含附件;如果BodyPart本身也是一个MIME的,则递归调用isContainAttach方法判断它是否包含附件;如果disposition为null,则获取BodyPart的contentType,如果contentType包含application或者name,也认为它包含附件。

(7)getMail方法获取邮件。

(8)saveMessageAsFile方法保存邮件本身。将邮件ID的尖括号部分当作邮件的文件名,根据邮件文件的存储路径和后缀名,构造邮件文件的存储路径。

  • 调用Message的writeTo方法将邮件的内容写入到输出流中。

  • 调用saveFile方法把输出流中的数据保存到文件。

(9)parseMessage方法分析邮件。

  • 调用getContent方法获得邮件的内容,如果是MIME邮件,则邮件内容的类型为Multipart。

  • 调用handleMultipart处理邮件,在handleMultipart方法中,依次处理Multipart包含的BodyPart,如果不是MIME邮件,则调用handlePart方法处理邮件。

  • handlePart方法处理一个BodyPart。通过它的getInputStream方法获得BodyPart的输入流。判断BodyPart的disposition属性是否为null,若是,则表示它是普通的邮件。

  • 根据contentType判断它的类型:text/plain表示文本邮件,保存到txt文件;text/html表示HTML邮件,保存到html文件;image/gif表示图片邮件,保存到gif文件;如果是其他类型,则保存到txt文件。调用saveFile方法将BodyPart的输入流保存到本地。


评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
  • 全部评论(0)
资料加载中...
已关注 , 取消