JavaMail實戰——內容解析(包含文本、圖片)

郵件內容的解析,包括:

  1. 發件人
  2. 收件人:收件人、抄送人、祕密抄送人
  3. 主題
  4. 發送時間
  5. 接收時間
  6. 消息id
  7. 消息所在文件夾
  8. 消息內容:文本內容和圖片,暫時不包含附件
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:[email protected]">
            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;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章