最近公司在做一个在自己产品上收发邮件的功能,我有幸参与了这个功能的研发。看了很多javamail的视频,但是大体讲的都十分基础。一些核心的问题,没有涉及。当然这也是要看自己在工作中真正遇到了哪些问题。
在我的负责的项目里,主要是遇到了“用javamail解析邮件内容(邮件内容是纯文本的时候),邮件内容重复”。
一些邮件发送出来时,part.getContentType()里既有plain又有html,这是为了防止一些无法解析html的地方也能收到邮件内容,所以才重复的发2段同样的内容, 这也造成了但当我们使用javamail的MimeMessage解析邮件内容时,解析出来的content重复。
解决方案:设一个text/plain的标识,如果邮件体里有text/plain,那解析完text/plain,就不能再解析text/html;如果邮件体里没有text/plain,就解析text/html
下面直接上具体代码(代码中带span标签的部分为重点!!刚用不知道为什么标记了颜色,发布文章后,变成了span标签,可能是因为我选的语言是java吧。)
public static void parseMessage(Message... messages) throws MessagingException, IOException {
if (messages == null || messages.length < 1)
throw new MessagingException("未找到要解析的邮件!");
// 解析所有邮件
for (int i = 0, count = messages.length; i < count; i++) {
MimeMessage msg = (MimeMessage) messages[i];
System.out.println("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- ");
System.out.println("messageID: " + msg.getMessageID());
System.out.println("主题: " + getSubject(msg));
System.out.println("发件人: " + getFrom(msg));
System.out.println("收件人:" + getReceiveAddress(msg, null));
System.out.println("发送时间:" + getSentDate(msg, null));
System.out.println("是否已读:" + isSeen(msg));
System.out.println("邮件优先级:" + getPriority(msg));
System.out.println("是否需要回执:" + isReplySign(msg));
System.out.println("邮件大小:" + msg.getSize() * 1024 + "kb");
boolean isContainerAttachment = isContainAttachment(msg);
System.out.println("是否包含附件:" + isContainerAttachment);
if (isContainerAttachment) {
saveAttachment(msg, "f:\\mailTest\\" + msg.getSubject() + "_" + i + "_"); // 保存附件--可将附件上传到自己公司的文件存储服务器上
}
StringBuffer content = new StringBuffer();
String contentType = msg.getContentType();
if (contentType.startsWith("text/plain")) {
getMailTextContent(msg, content,true);
} else
getMailTextContent(msg,content, false);
System.out.println("邮件正文:" + content);
System.out.println("------------------第" + msg.getMessageNumber() + "封邮件解析结束-------------------- ");
System.out.println();
}
}
public static void getMailTextContent(Part part, StringBuffer content,boolean plainFlag) throws MessagingException, IOException {
//如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
if (part.isMimeType("text/html") && !isContainTextAttach && plainFlag == false) {
content.append(MimeUtility.decodeText(part.getContent().toString()));
} else if(part.isMimeType("text/plain") && !isContainTextAttach && plainFlag){
content.append(part.getContent().toString());
plainFlag = false;
} else if (part.isMimeType("message/rfc822")) {
getMailTextContent((Part)part.getContent(),content,plainFlag);
} 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,plainFlag);
}
}
}
public static void saveAttachment(Part part, String destDir)
throws UnsupportedEncodingException, MessagingException, FileNotFoundException, IOException {
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);
// 某一个邮件体也有可能是由多个邮件体组成的复杂体
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);
}
}
public static String getReceiveAddress(MimeMessage msg, Message.RecipientType type) throws MessagingException {
StringBuffer receiveAddress = new StringBuffer();
Address[] addresss = null;
if (type == null) {
addresss = msg.getAllRecipients();
} else {
addresss = msg.getRecipients(type);
}
if (addresss == null || addresss.length < 1)
throw new MessagingException("没有收件人!");
for (Address address : addresss) {
InternetAddress internetAddress = (InternetAddress) address;
receiveAddress.append(internetAddress.toUnicodeString()).append(",");
}
receiveAddress.deleteCharAt(receiveAddress.length() - 1); // 删除最后一个逗号
return receiveAddress.toString();
}