JavaEE-JavaMail 06 邮件解析

解析邮件的工具类

/********************************************************************************
 * Project Name      [JavaEE_Components]
 * File Name         [MailUtils.java]
 * Creation Date     [2015-01-01]
 * 
 * Copyright© [email protected] All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package javamail.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

/**
 * Email工具类
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class MailUtils {

    /**
     * 根据指定的文件名生成附件
     * 
     * @param fileName
     *            文件名
     * @return
     * @throws Exception
     */
    public static MimeBodyPart createMailAttachment(File fileName) throws Exception {
        MimeBodyPart attachment = new MimeBodyPart();
        DataSource dataSource = new FileDataSource(fileName);
        DataHandler dataHandler = new DataHandler(dataSource);
        attachment.setDataHandler(dataHandler);
        attachment.setFileName(MimeUtility.encodeText(dataSource.getName()));
        return attachment;
    }

    /**
     * 根据指定路径的文件名生成附件
     * 
     * @param filePath
     *            附件所在的文件路径
     * @return
     * @throws Exception
     */
    public static MimeBodyPart createMailAttachment(String filePath) throws Exception {
        File file = new File(filePath);
        return createMailAttachment(file);
    }

    /**
     * 根据指定的邮件正文文本和文件[图片或其他]路径生成混合的邮件文本
     * 
     * @param body
     *            邮件正文内容
     * @param filePath
     *            图片或其他文件路径
     * @return
     * @throws Exception
     */
    public static MimeBodyPart createMailBodyContent(String body, String filePath) throws Exception {
        // 内容
        MimeBodyPart mailBody = new MimeBodyPart();

        // 邮件正文内容[html + image]
        MimeMultipart mailBodyMP = new MimeMultipart("related");
        MimeBodyPart otherPart = new MimeBodyPart();
        MimeBodyPart htmlPart = new MimeBodyPart();
        mailBodyMP.addBodyPart(otherPart);
        mailBodyMP.addBodyPart(htmlPart);

        // 其他内容
        DataSource dataSource = new FileDataSource(new File(filePath));
        DataHandler dataHandler = new DataHandler(dataSource);
        otherPart.setDataHandler(dataHandler);
        otherPart.setContentID(MimeUtility.encodeText(dataSource.getName()));

        // 邮件内容
        MimeMultipart htmlMP = new MimeMultipart("alternative");
        MimeBodyPart htmlContent = new MimeBodyPart();
        htmlContent.setContent(
                "<span style='color: red'>带附件的Html邮件 <img src='cid:" + otherPart.getContentID() + "' /></span>",
                "text/html;charset=UTF-8");
        htmlMP.addBodyPart(htmlContent);
        htmlPart.setContent(htmlMP);

        mailBody.setContent(mailBodyMP);
        return mailBody;
    }

    /**
     * 根据指定的MimeBodyPart生成邮件
     * 
     * @param bodyParts
     * @return
     * @throws Exception
     */
    public static MimeMultipart createMixedBodyContent(MimeBodyPart... bodyParts) throws Exception {
        MimeMultipart mailContent = new MimeMultipart("mixed");

        for (MimeBodyPart mimeBodyPart : bodyParts) {
            mailContent.addBodyPart(mimeBodyPart);
        }

        return mailContent;
    }

    /**
     * 根据邮件内容生成eml文件
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static File createEmlFile(String dir, Message message) throws Exception {
        File file = new File(dir + MimeUtility.decodeText(message.getSubject()) + ".eml");
        message.writeTo(new FileOutputStream(file));
        return file;
    }

    /**
     * 发送已生成的eml文件
     * 
     * @param emlFile
     * @param properties
     * @param auth
     * @throws Exception
     */
    public static void sendMailFromEmlFile(File emlFile, Properties properties, Authenticator auth) throws Exception {
        Session session = Session.getInstance(properties, auth);
        sendMailFromEmlFile(emlFile, session);
    }

    /**
     * 发送已生成的eml文件
     * 
     * @param emlFile
     * @param session
     * @throws Exception
     */
    public static void sendMailFromEmlFile(File emlFile, Session session) throws Exception {
        MimeMessage message = new MimeMessage(session, new FileInputStream(emlFile));
        Transport.send(message);
    }

    /**
     * 获取邮件的主题
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static String getMailSubject(Message message) throws Exception {
        return MimeUtility.decodeText(message.getSubject());
    }

    /**
     * 获取邮件的发件人
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static String getMailSender(Message message) throws Exception {
        String emailSender = null;
        Address[] addresses = message.getFrom();
        if (addresses == null || addresses.length < 1) {
            throw new IllegalArgumentException("该邮件没有发件人");
        }

        // 获得发件人
        InternetAddress address = (InternetAddress) addresses[0];
        String senderName = address.getPersonal();
        if (senderName != null) {
            senderName = MimeUtility.decodeText(senderName);
            emailSender = senderName + "<" + address.getAddress() + ">";
        } else {
            senderName = address.getAddress();
        }
        return emailSender;
    }

    /**
     * 根据收件人类型, 获得邮件的收件人
     * 
     * @param message
     * @param recipientType
     * @return
     * @throws Exception
     */
    public static String getMailRecipients(Message message, Message.RecipientType recipientType) throws Exception {
        StringBuilder builder = new StringBuilder();

        Address[] addresses = null;
        if (recipientType == null) {
            addresses = message.getAllRecipients();
        } else {
            addresses = message.getRecipients(recipientType);
        }

        if (addresses == null || addresses.length < 1) {
            throw new IllegalArgumentException("该邮件没有收件人");
        }

        for (Address address : addresses) {
            InternetAddress iAddress = (InternetAddress) address;
            builder.append(iAddress.toUnicodeString()).append(", ");
        }

        return builder.deleteCharAt(builder.length() - 1).toString();
    }

    /**
     * 获得邮件发送时间
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static String getMailSendDate(Message message, String pattern) throws Exception {
        String sendDateString = null;

        if (pattern == null || "".equals(pattern.trim())) {
            pattern = "yyyy年MM月dd日 E HH:mm";
        }

        Date sendDate = message.getSentDate();
        sendDateString = new SimpleDateFormat(pattern).format(sendDate);

        return sendDateString;
    }

    /**
     * 邮件是否包含附件<br/>
     * 
     * multipart/* 代表附件<br/>
     * message/rfc822 代表了内嵌消息
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static boolean containsAttachment(Part part) throws Exception {
        boolean flag = false;
        if (part != null) {
            if (part.isMimeType("multipart/*")) {
                MimeMultipart mp = (MimeMultipart) part.getContent();
                for (int i = 0; i < mp.getCount(); i++) {
                    BodyPart bodyPart = mp.getBodyPart(i);
                    String disposition = bodyPart.getDisposition();
                    if (disposition != null && (Part.ATTACHMENT.equalsIgnoreCase(disposition)
                            || Part.INLINE.equalsIgnoreCase(disposition))) {
                        flag = true;
                    } else if (bodyPart.isMimeType("multipart/*")) {
                        flag = containsAttachment(bodyPart);
                    } else {
                        String contentType = bodyPart.getContentType();
                        if (contentType.indexOf("application") != -1) {
                            flag = true;
                        }

                        if (contentType.indexOf("name") != -1) {
                            flag = true;
                        }
                    }
                    if (flag)
                        break;
                }
            } else if (part.isMimeType("message/rfc822")) {
                flag = containsAttachment((Part) part.getContent());
            }
        }

        return flag;
    }

    /**
     * 邮件是否已读
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static boolean isSeen(Message message) throws Exception {
        if (message == null) {
            throw new MessagingException("Message is empty");
        }
        return message.getFlags().contains(Flags.Flag.SEEN);
    }

    /**
     * 邮件是否含有阅读回执
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static boolean isReplaySign(Message message) throws Exception {
        if (message == null) {
            throw new MessagingException("Message is empty");
        }

        boolean replaySign = false;
        String[] headers = message.getHeader("Disposition-Notification-To");
        if (headers != null && headers.length > 0) {
            replaySign = true;
        }

        return replaySign;
    }

    /**
     * 获得邮件的优先级
     * 
     * @param message
     * @return
     * @throws Exception
     */
    public static String getMailPriority(Message message) throws Exception {
        if (message == null) {
            throw new MessagingException("Message is empty");
        }

        String priority = "普通";

        String[] headers = message.getHeader("X-Priority");
        if (headers != null && headers.length > 0) {
            String mailPriority = headers[0];
            if (mailPriority.indexOf("1") != -1 || mailPriority.indexOf("High") != -1) {
                priority = "紧急";
            } else if (mailPriority.indexOf("5") != -1 || mailPriority.indexOf("Low") != -1) {
                priority = "低";
            } else {
                priority = "普通"; // 3或者Normal;
            }

        }

        return priority;
    }

    /**
     * 获得邮件文本内容
     * 
     * @param part
     * @param content
     * @throws Exception
     */
    public static void getMailTextContent(Part part, StringBuilder content) throws Exception {
        if (part == null) {
            throw new MessagingException("Message content is empty");
        }
        boolean containsTextInAttachment = part.getContentType().indexOf("name") > 0;
        if (part.isMimeType("text/*") && containsTextInAttachment) {
            content.append(part.getContent().toString());
        } else if (part.isMimeType("message/rfc822")) {
            getMailTextContent((Part) part.getContent(), content);
        } else if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart bodyPart = mp.getBodyPart(i);
                getMailTextContent(bodyPart, content);
            }
        } else if (part.isMimeType("image/*")) {
            // TODO part.getInputStream()获得输入流然后输出到指定的目录
        } else {
            // TODO 其它类型的contentType, 未做处理, 直接输出
            content.append(part.getContent().toString());
        }
    }

    /**
     * 保存附件
     * 
     * @param part
     * @param destDir
     * @throws Exception
     */
    public static void saveAttachment(Part part, String destDir) throws Exception {
        if (part == null) {
            throw new MessagingException("part is empty");
        }

        // 复杂的邮件包含多个邮件体
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            // 遍历每一个邮件体
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart bodyPart = mp.getBodyPart(i);
                // bodyPart也可能有多个邮件体组成
                String disposition = bodyPart.getDisposition();
                if (disposition == null && (Part.ATTACHMENT.equalsIgnoreCase(disposition)
                        || Part.INLINE.equalsIgnoreCase(disposition))) {
                    InputStream in = bodyPart.getInputStream();
                    saveFile(in, 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);
        }
    }

    /**
     * 保存文件到指定目录
     * 
     * @param in
     * @param destDir
     * @param fileName
     * @throws Exception
     */
    public static void saveFile(InputStream in, String destDir, String fileName) throws Exception {

        FileOutputStream out = new FileOutputStream(new File(destDir + fileName));

        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = in.read(buffer)) != -1) {
            out.write(buffer, 0, length);
        }

        out.close();
        in.close();
    }

    /**
     * 解码文本
     * 
     * @param encodedText
     * @return
     * @throws Exception
     */
    public static String decodeText(String encodedText) throws Exception {
        if (encodedText == null || "".equals(encodedText.trim())) {
            return "";
        } else {
            return MimeUtility.decodeText(encodedText);
        }
    }
}

解析邮件的测试类

/********************************************************************************
 * Project Name      [JavaEE_Components]
 * File Name         [ParsingMails.java]
 * Creation Date     [2015-01-01]
 * 
 * Copyright© [email protected] All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package javamail.mail;

import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;

import org.junit.Before;
import org.junit.Test;

import javamail.utils.MailAuthenticator;
import javamail.utils.MailConstants;
import javamail.utils.MailUtils;
import javamail.utils.PasswordUtils;

/**
 * 解析邮件
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class ParsingMails {

    private static Properties properties = null;

    private static String emailAddress = "[email protected]";

    @Before
    public void init() {
        properties = new Properties();
        properties.put("mail.store.protocol", MailConstants.PROTOCAL_POP3);
        properties.put("mail.pop3.host", MailConstants.POP3_HOST_OF_SINA);
        properties.put("mail.pop3.port", MailConstants.POP3_PORT_OF_SINA);
        properties.put("mail.pop3.auth", MailConstants.IS_AUTHORIZATION_NEED);
        properties.put("mail.debug", String.valueOf(MailConstants.IS_DEBUG_MOD_ENABLED));
    }

    /**
     * 解析邮件
     * 
     * @throws Exception
     */
    public static void parseMails() throws Exception {
        // 创建Session对象并连接到指定的邮箱
        Session session = Session.getInstance(properties,
                new MailAuthenticator(emailAddress, PasswordUtils.readPassword(emailAddress)));
        Store store = session.getStore();
        store.connect(emailAddress, PasswordUtils.readPassword(emailAddress));

        // 获得收件箱
        Folder folder = store.getFolder("INBOX");
        // 以只读权限打开收件箱, 还可以配置为Folder.READ_WRITE
        folder.open(Folder.READ_ONLY);

        // 得到收件箱里所有的邮件
        Message[] messages = folder.getMessages();

        // 解析邮件
        for (Message message : messages) {
            System.out.println("第" + message.getMessageNumber() + "封邮件 ");
            System.out.println("邮件主题:     " + MailUtils.getMailSubject(message));
            System.out.println("邮件发件人:   " + MailUtils.getMailSender(message));
            System.out.println("邮件收件人:   " + MailUtils.getMailRecipients(message, null));
            System.out.println("邮件发送时间: " + MailUtils.getMailSendDate(message, null));
            System.out.println("邮件是否已读: " + MailUtils.isSeen(message));
            System.out.println("邮件的优先级: " + MailUtils.getMailPriority(message));
            System.out.println("是否需要回执: " + MailUtils.isReplaySign(message));
            System.out.println("邮件的大小:   " + message.getSize() * 1024 + "KB");
            boolean containerAttachment = MailUtils.containsAttachment(message);
            System.out.println("是否包含附件: " + containerAttachment);
            if (containerAttachment) {
                MailUtils.saveAttachment(message, "Z:/temp/" + message.getSubject() + "_");
            }
            StringBuilder content = new StringBuilder(30);
            MailUtils.getMailTextContent(message, content);
            System.out.println("邮件正文: " + (content.length() > 100 ? content.subSequence(0, 100) + "......" : content));
            System.out.println();
        }

        folder.close(true);
        store.close();
    }

    @Test
    public void testParseMails() throws Exception {
        parseMails();
    }
}


你可能感兴趣的:(javaee,javamail)