最近公司在做一个在自己产品上收发邮件的功能,我有幸参与了这个功能的研发。看了很多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();
	}