公司项目中,需要将邮箱功能集成到自应用中,碰到的问题是,邮件正文若包含 text/plain和text/html,则会两个都获取,导致需要阅读的内容出现两次,一次是有格式的,一次是没有格式的,若只获取text/html,则有可能正文中只有text/plain的有内容,会导致正文内容为空,所以对获取正文的部分进行了调整
解析邮件
/**
* 解析邮件
*/
@Transactional
public void parseMessage(IMAPFolder imapFolder, CrmMailAccountEntity account, Long folderId, Message... messages) throws Exception {
if (messages == null || messages.length < 1) {
// throw new MessagingException("未找到要解析的邮件!");
System.out.println("未找到需要解析的邮件");
return;
}
// 解析所有邮件
Date now = new Date();
for (int i = 0, count = messages.length; i < count; i++) {
//其他内容暂时省略
//获取正文内容
StringBuffer content = new StringBuffer(30);
MailContentVo contentVo = new MailContentVo();
contentVo.setContent(content).setContainPlain(false);
getMailTextContent(msg, contentVo);
//contentVo中的content即为获取后的正文内功
String mailContent = contentVo.getContent().toString();
}
}
contentVo的类
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class MailContentVo {
private StringBuffer content;
private boolean containPlain;
}
解析邮件正文内容
/**
* 获得邮件文本内容
*
* @param part 邮件体
* @param contentVo 存储邮件文本内容的字符串
* @throws MessagingException
* @throws IOException
*/
public static void getMailTextContent(Part part, MailContentVo contentVo) throws MessagingException, IOException {
//如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
//此处若为 "text/*" ,则会先获取w无格式的文本,再获取html格式的文本,故只抓取html格式的文本内容
//若是从multipart/*中取得正文内容,并且text/plain中有内容,则将contentVo中的isContainPlain设置为true,后面若还包含text/html,则将contentVo中content删除,重新设置text/html中的内容即可
if (part.isMimeType("text/html") && !isContainTextAttach) {
if(contentVo.isContainPlain()){
contentVo.getContent().delete(0, contentVo.getContent().length());
}
contentVo.getContent().append(part.getContent().toString());
//若邮件正文不是html格式,则需要在判断一遍是否为文本格式,否则会导致抓取的邮件内容为空
} else if (part.isMimeType("text/plain")) {
contentVo.getContent().append(part.getContent().toString());
contentVo.setContainPlain(true);
} else if (part.isMimeType("message/rfc822")) {
getMailTextContent((Part) part.getContent(), contentVo);
} 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, contentVo);
}
}
}
```