邮件内容的解析,包括:
- 发件人
- 收件人:收件人、抄送人、秘密抄送人
- 主题
- 发送时间
- 接收时间
- 消息id
- 消息所在文件夹
- 消息内容:文本内容和图片,暂时不包含附件
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.mail.Folder;
import javax.mail.Header;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
public class MailParser {
private MimeMessage mimeMessage = null;
private String bodyText = "";
private String from;
private String to;
private String cc;
private String bcc;
private String subject;
private Date sentDate;
private Date receivedDate;
private String messageID;
private String box;
private static Logger logger = Logger.getLogger(MailParser.class);
public MailParser(MimeMessage mimeMessage) {
this.mimeMessage = mimeMessage;
parse();
logger.debug("创建一个MailParser对象....");
}
private void parse() {
Folder folder = this.mimeMessage.getFolder();
try {
if (!folder.isOpen()) {
folder.open(Folder.READ_ONLY);
}
this.from = genFrom();
this.to = address(getMailAddress(EnumRecipientType.TO));
this.cc = address(getMailAddress(EnumRecipientType.CC));
this.bcc = address(getMailAddress(EnumRecipientType.BCC));
this.subject = MimeUtility.decodeText(mimeMessage.getSubject());
this.sentDate = mimeMessage.getSentDate();
this.receivedDate = mimeMessage.getReceivedDate();
// 邮件内容解析开始>>>>>>>存放邮件内容的StringBuffer对象
StringBuffer bodyTextBuf = new StringBuffer();
Map<String, String> imgs = new HashMap<String, String>();
getMailContent(bodyTextBuf, imgs, this.mimeMessage);
String tmpContent = bodyTextBuf.toString();
//替换原文中的图片,原始图片标签为<img src="cid:image001.jpg@01D24963.3B4B8280">
for (String contentId : imgs.keySet()) {
String replacedText = "cid:" + contentId.replace("<", "").replace(">", "");
tmpContent = tmpContent.replace(replacedText, imgs.get(contentId));
}
bodyText = tmpContent;
// <<<<<<<<邮件内容解析结束
this.messageID = mimeMessage.getMessageID();
this.box = mimeMessage.getFolder().getName();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
folder.close(false);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
public static String address(String personaddress) {
if (StringUtils.isEmpty(personaddress)) {
return "";
}
String regex = ".*<(.*)>.*";
Pattern p = Pattern.compile(regex);
List<String> list = new ArrayList<String>();
for (String pa : personaddress.split(";")) {
Matcher matcher = p.matcher(pa);
if (matcher.matches()) {
String addr = matcher.group(1);
list.add(addr);
}
}
return StringUtils.join(list.toArray(new String[0]), ";");
}
public String genFrom() throws MessagingException {
InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
String from = address[0].getAddress();
if (from == null) {
from = "";
logger.warn("发送人邮箱地址为空!");
}
return from;
}
/**
* * 获得发件人的地址和姓名
*
*/
public String getFrom() {
return from;
}
/**
* 收件人
*
* @return
*/
public String getTo() {
return this.to;
}
/**
* 抄送人
*
* @return
*/
public String getCc() {
return this.cc;
}
/**
* 私密抄送
*
* @return
*/
public String getBcc() {
return this.bcc;
}
/**
* <p>
* 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同
* </p>
*
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
private String getMailAddress(EnumRecipientType type) throws MessagingException, UnsupportedEncodingException {
String mailAddr = "";
InternetAddress[] address = null;
switch (type) {
case TO:
address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.TO);
break;
case CC:
address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.CC);
break;
case BCC:
address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.BCC);
break;
}
if (address != null) {
String[] addrs = new String[address.length];
int i = 0;
for (InternetAddress addr : address) {
String emailAddr = MimeUtility.decodeText(addr.getAddress());
String personal = MimeUtility.decodeText(addr.getPersonal());
addrs[i++] = personal + "<" + emailAddr + ">";
}
mailAddr = StringUtils.join(addrs, ",");
}
return mailAddr;
}
/**
* 获得邮件主题
*
*/
public String getSubject() {
return this.subject;
}
/**
* 邮件发送日期
*
* @return
*/
public Date getSentDate() {
return this.sentDate;
}
/**
* 邮件接收日期
*
* @return
*/
public Date getReceivedDate() {
return this.receivedDate;
}
/**
* 获得邮件正文内容
*
* @return
*/
public String getBodyText() {
return bodyText;
}
/**
* <p>
* 解析邮件
* </p>
*
* <pre>
* 主要是根据MimeType类型的不同执行不同的操作,一步一步的解析
* 把得到的邮件内容保存到一个StringBuffer对象中
* </pre>
*
* @throws MessagingException
* @throws IOException
*/
public static void getMailContent(StringBuffer sb, Map<String, String> imgs, Part p) throws Exception {
if (p.isMimeType("text/plain")) {// 检查内容是否为纯文本
logger.warn("skip text plain");
} else if (p.isMimeType("text/html")) {// 检查内容是否为html
sb.append(p.getContent());
} else if (p.isMimeType("multipart/*")) {// 检查内容是否含有附件
Multipart mp = (Multipart) p.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++) {
getMailContent(sb, imgs, mp.getBodyPart(i));
}
} else if (p.isMimeType("message/rfc822")) {// 检查内容是否含有嵌套消息
getMailContent(sb, imgs, (Part) p.getContent());
} else if (p.isMimeType("image/*")) {// 检查内容是否为内嵌图片
Object content = p.getContent();
String contentID = ((String[]) p.getHeader("Content-ID"))[0];
InputStream in = (InputStream) content;
byte[] bArray = new byte[in.available()];
while (((InputStream) in).available() > 0) {
int result = (int) (((InputStream) in).read(bArray));
if (result == -1) {
break;
}
}
in.close();
// 文件下载开始
int i = imgs.size();
String fileName = "/tmp/" + i + ".jpg";
FileOutputStream f2 = new FileOutputStream(fileName);
f2.write(bArray);
f2.close();
in.close();
imgs.put(contentID, fileName);
// 文件下载结束
} else {
logger.warn("This is an unknown type:" + p.getContentType());
}
}
/**
* 获得此邮件的Message-ID
*/
public String getMessageId() {
return this.messageID;
}
public String getBox() {
return this.box;
}
public void printHeaders() {
try {
Enumeration<Header> allHeaders = mimeMessage.getAllHeaders();
while (allHeaders.hasMoreElements()) {
Header header = allHeaders.nextElement();
System.out.println(header.getName() + "-->" + header.getValue());
}
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
/**
* 邮件接收类型枚举
* @data Nov 29, 2016 2:57:11 PM
*/
enum EnumRecipientType {
TO("To")/* 收件人 */, CC("Cc")/* 抄送 */, BCC("Bcc")/* 密件抄送 */;
private String code;
EnumRecipientType(String code) {
this.code = code;
}
public String code() {
return this.code;
}
}