基于JavaMail获取邮件的工具类

对象中不单纯有参数,还有执行的方法,偏向富血

使用该包有几个好处:
1. 简易获取邮箱Session
2. 只要获取到邮件,初始化 MailMessage 后,可通过调用单一方法从而获取 发件人、收件人、抄送人、主题、内容、内容中的图片、附件等

pom文件增加依赖:

<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.16</version>
    <scope>provided</scope>
</dependency>

<!-- javamail -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.1</version>
</dependency>

<!-- guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>25.1-jre</version>
</dependency>

<!-- html 解析 -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.11.3</version>
</dependency>

<!-- log4j2 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.11.0</version>
</dependency>

日志文件log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

包结构为:

---com
    |---test
        |---build
        |---common
            |---enums
        |---domain
        |---pojo

JavaMail 会话创建类:

package com.test.build;

import com.test.common.enums.MailProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import java.util.Properties;

/**
 * 仿照 Camel MailConfiguration
 * https://www.cnblogs.com/15ho/p/5907174.html
 * https://javaee.github.io/javamail/docs/api/com/sun/mail/imap/package-summary.html
 *
 * IMAPBuilder.sessionBuilder(MailProtocol.IMAPS)
 *      .host("imap.exmail.qq.com")
 *      .username("xxx@qq.com")
 *      .password("你猜")
 *      .connectionTimeout(12345)
 *      .build();
 *
 * SearchTerm 试了 YoungerTerm OlderTerm SentDateTerm ,前两者服务器不支持,后者支持但其实查询无效
 * @author chenyunan 2018/6/15 9:16
 */
public class IMAPBuilder {

    private static final Logger logger = LoggerFactory.getLogger(IMAPBuilder.class);

    public static SessionBuilder sessionBuilder() {
        return new SessionBuilder();
    }

    public static SessionBuilder sessionBuilder(MailProtocol mailProtocol) {
        return new SessionBuilder().mailProtocol(mailProtocol);
    }

    /**
     * 邮件Session构造器
     */
    public static class SessionBuilder {

        private MailProtocol mailProtocol;
        private int connectionTimeout = 0; //milliseconds default infinite
        private String host;
        private int port; // 默认0
        private int fetchSize = 4; // 每次附件获取的Buffer大小,单位:mb

        private String username;
        private String password;

        private boolean debugMode = false;

        public SessionBuilder mailProtocol(MailProtocol mailProtocol) {
            this.mailProtocol = mailProtocol;
            return this;
        }

        public SessionBuilder host(String host) {
            this.host = host;
            return this;
        }

        /**
         * 不填默认为0
         * <p/>
         * -1 使用系统默认
         * 0 使用硬编码自动适配默认
         */
        public SessionBuilder port(int port) {
            this.port = port;
            return this;
        }

        /**
        * 每次附件获取的Buffer大小,单位:mb
        */
        public SessionBuilder fetchSize(int fetchSize) {
            this.fetchSize = fetchSize;
            return this;
        }

        /**
        * 获取连接的超时时间
        */
        public SessionBuilder connectionTimeout(int connectionTimeout) {
            this.connectionTimeout = connectionTimeout;
            return this;
        }

        /**
        * 邮箱
        */
        public SessionBuilder username(String username) {
            this.username = username;
            return this;
        }

        /**
        * 邮箱密码
        */
        public SessionBuilder password(String password) {
            this.password = password;
            return this;
        }

        /**
        * 创建会话
        */
        public Session build() {
            if(mailProtocol == null) {
                throw new IllegalArgumentException("未传递MailProtocol");
            }
            Session session = Session.getDefaultInstance(createJavaMailProperties(), new DefaultAuthenticator(username, password));
            session.setDebug(debugMode);
            return session;
        }

        /**
         * 无需写入ssl参数,只要把协议 imaps 写入即可
         */
        private Properties createJavaMailProperties() {
            // clone the system properties and set the java mail properties
            Properties properties = (Properties)System.getProperties().clone();
            if(connectionTimeout != 0) {
                properties.put("mail." + mailProtocol.getProtocol() + ".connectiontimeout", connectionTimeout);
                properties.put("mail." + mailProtocol.getProtocol() + ".timeout", connectionTimeout);
            }
            properties.put("mail." + mailProtocol.getProtocol() + ".host", host);
            if(port == 0) {
                port = mailProtocol.getPort();
            }
            properties.put("mail." + mailProtocol.getProtocol() + ".port", "" + port);
            if (username != null) {
                properties.put("mail." + mailProtocol.getProtocol() + ".user", username);
                properties.put("mail.user", username);
                properties.put("mail." + mailProtocol.getProtocol() + ".auth", "true");
            } else {
                properties.put("mail." + mailProtocol.getProtocol() + ".auth", "false");
            }
            properties.put("mail.transport.protocol", mailProtocol.getProtocol());
            properties.put("mail.store.protocol", mailProtocol.getProtocol());
            properties.put("mail.host", host);

            properties.put("mail." + mailProtocol.getProtocol() + ".fetchsize", fetchSize * 1024 * 1000);

            if (debugMode) {
                // add more debug for the SSL communication as well
                properties.put("javax.net.debug", "all");
            }

            return properties;
        }

    }

    /**
     * Mail {@link Authenticator} that supplies username and password
     */
    public static class DefaultAuthenticator extends Authenticator {

        private final String username;
        private final String password;

        public DefaultAuthenticator(String username, String password) {
            this.password = password;
            this.username = username;
        }

        /**
         * Returns an authenticator object for use in sessions
         */
        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }

    }

}

实际邮件对象与处理类(领域模型):

package com.test.domain;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.test.common.enums.FileType;
import com.test.pojo.FileFullPathType;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 参考:https://blog.csdn.net/caoyishuai/article/details/7870418
 *
 * 根据业务获取指定参数
 * <p/>
 *      Multipart multipart = (Multipart) imapMessage.getContent();
 *      multipart.getBodyPart(index);
 * <p/>
 *      part.isMimeType(MimeType)
 * <p/>
 *      内容,媒体类型分为下列几种:
 *          1、text/plain:只包含文本,不包含图片等
 *          2、text/html:包含完整html
 *          3、multipart/*:关联类型,有子类型
 *          4、message/rfc822:电子邮件标准格式,各种参数:https://baike.baidu.com/item/RFC%20822/1468155
 *          5、其他:文件、流、图片等
 * <p/>
 *      附件,媒体类型分为下列几种:
 *          1、multipart/*:关联类型,有子类型
 *          2、APPLICATION/OCTET-STREAM:流,通常是附件
 *          3、IMAGE/JPEG:图片,正常是与text/html内中通过Content-ID关联
 * <p/>
 *      关闭流不在本类
 * @author chenyunan 2018/6/15 11:55
 */
public class MailMessage {

    /**
     * 初始化Mail对象
     */
    public static MailMessage init(Message message) {
        return new MailMessage().message(message);
    }

    private Message message;

    private String subject;

    private String from;
    private String fromPersonal;
    private String fromMail;

    private String[] tos;
    private Map<String, String[]> toPersonalMails = new HashMap<>();

    private String[] ccs;
    private Map<String, String[]> ccPersonalMails = new HashMap<>();

    private String body;
    /**
     * 替换过src的body
     */
    private String replaceBody;

    private String[] attachments;
    // MAIL-UUID fileName inputstream
    private Table<String, String, InputStream> srcAttachmentStream;
    // MAIL-UUID fileFullPath
    private Map<String, String> contentIdFullPath;

    private boolean have2Close = false;

    private MailMessage message(Message message) {
        this.message = message;
        return this;
    }

    /**
     * 执行完附件获取流,此时统一关闭或Folder关闭时统一关闭
     */
    public boolean isHave2Close() {
        return have2Close;
    }

    /**
     * 做 content-type = text/html 格式的src替换 <br>
     * 获取 邮件中的:
     * <br>
     * row:邮件的UUID ,默认填充 文件名 或 邮件的Content-ID
     * <br>
     * column:文件名
     * <br>
     * value:流,如果不使用需要需要关闭
     */
    public Table<String, String, InputStream> srcAttachmentStream() throws IOException, MessagingException {
        attachments();
        return srcAttachmentStream;
    }

    /**
     *
     */
    @Deprecated
    public Map<String, String> contentIdFullPath(String prefixFilePath) throws IOException, MessagingException {
        if(contentIdFullPath == null) {
            srcAttachmentStream();
            contentIdFullPath = new HashMap<>();
            // tODO
        }
        return contentIdFullPath;
    }

    /**
     * 附件名称
     */
    public String[] attachments() throws IOException, MessagingException {
        if(attachments == null) {
            have2Close = true;
            srcAttachmentStream = HashBasedTable.create();
            Object content = message.getContent();
            if(content == null) {
                attachments = new String[0];
            } else if(content instanceof Multipart) {
                multiPartAttachments((Multipart) content);
                Set<String> fileNames = srcAttachmentStream.columnKeySet();
                attachments = new String[fileNames.size()];
                fileNames.toArray(attachments);
            } else {
                attachments = new String[0];
            }
        }
        return attachments;
    }

    /**
     * 嵌套类型
     * MIMETYPE=multipart/* 的对象,为数组,内部有多个嵌套类型
     */
    private void multiPartAttachments(Multipart multipart) throws MessagingException, IOException {
        for(int i=0, count=multipart.getCount(); i < count; i++) {
            relativeAttachments(multipart.getBodyPart(i));
        }
    }

    /**
     * 嵌套类型下的类型处理
     * MIMETYPE=可能为multipart/*(嵌套类型), message/rfc822(邮件类型), application/*(应用,实际附件)
     */
    private void relativeAttachments(Part part) throws MessagingException, IOException {
        if(part.isMimeType(MULTIPART_ALL)) {
            multiPartAttachments((Multipart) part.getContent());
        } else if(part.isMimeType(MESSAGE_RFC822)) {
            relativeAttachments((Part) part.getContent());
        } else if(part.isMimeType(APPLICATION_ALL)) {
            gatherAttachments(part);
        } else {
            logger.info("其他类型[{}]", part.getContentType());
            gatherAttachments(part);
        }
    }

    private static final Logger logger = LoggerFactory.getLogger(MailMessage.class);

    /**
     * 应用类型,附件实际可能保存的位置
     * 提取附件,application/* 是附件,其他可能是插入文本的照片
     */
    private void gatherAttachments(Part part) throws MessagingException, IOException {
        String disposition = part.getDisposition();
        if(disposition != null
                && (disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE))) {
            extractAttachment((BodyPart) part);
        } else if(part.isMimeType(MULTIPART_ALL)) {
            multiPartAttachments((Multipart) part.getContent());
        } else {
            logger.info("默认类型是啥{}", part.getContentType());
            extractAttachment((BodyPart) part);
        }
    }

    /**
     * 提取附件
     */
    private void extractAttachment(BodyPart mpart) throws IOException, MessagingException {
        String fileName = mpart.getFileName();
        if (checkFileName(fileName)) {
            fileName = MimeUtility.decodeText(fileName);
            String id;
            if(mpart.getHeader(CONTENT_ID) != null && mpart.getHeader(CONTENT_ID).length > 0) {
                id = mpart.getHeader(CONTENT_ID)[0]
                        .replace(LEFT_ANGLE_BUCKET, BLANK).replace(RIGHT_ANGLE_BUCKET, BLANK);
            } else {
                id = fileName;
            }
            srcAttachmentStream.put(id, fileName, mpart.getInputStream());
        }
    }

    private static final String CONTENT_ID = "Content-ID";
    private static final String LEFT_ANGLE_BUCKET = "<";
    private static final String RIGHT_ANGLE_BUCKET = ">";
    private static final String BLANK = "";

    /**
     * 是不是可以解析的文件名
     */
    private static boolean checkFileName(String fileName) {
        return fileName != null
                && (fileName.toLowerCase().indexOf("gb2312") != -1
                || fileName.toLowerCase().indexOf("gb18030") != -1
                || fileName.toLowerCase().indexOf("gbk") != -1
                || fileName.toLowerCase().indexOf("utf-8") != -1);
    }

    /**
     * 内容,媒体类型=text/html,text/plain不获取
     */
    public String body() throws MessagingException, IOException {
        if(body == null) {
            Object content = message.getContent();
            if(content == null) {
                body = "";
            } else if(content instanceof Multipart) {
                Multipart multipart = (Multipart) content;
                StringBuilder htmlBuilder = new StringBuilder();
                for(int i=0, count = multipart.getCount(); i < count; i++) {
                    multipartContent(multipart.getBodyPart(i), htmlBuilder);
                }
                body = htmlBuilder.toString().replaceAll("\\[\\r|\\r\\n|\\n\\]", "");
            } else if(content instanceof String) {
                body = ((String) content).replaceAll("\\[\\r|\\r\\n|\\n\\]", "");
            }
            // warning 这里是为了替换html文本中的编码方式,如果还是要保留GB2312把下边两段去掉
            if(body != null) {
                body.replace("GB2312", "UTF-8");
                body.replace("gb2312", "UTF-8");
            }
        }
        return body;
    }

    /**
     * 将内容中的src替换
     * <p/>
     *   原始:src="cid:xxxxxxx"
     *   替换:文件路径,如:src="/abc/abc.jpg"
     */
    public String replaceBody(Map<String, FileFullPathType> contentIdFileFullPath) throws IOException, MessagingException {
        if(replaceBody == null) {
            replaceImgSrc(contentIdFileFullPath);
        }
        return replaceBody;
    }

    /**
     * 替换照片中的文件地址
     */
    private void replaceImgSrc(Map<String, FileFullPathType> contentIdFileFullPath) throws IOException, MessagingException {
        body();
        if(contentIdFileFullPath != null && !contentIdFileFullPath.isEmpty()) {
            Document document = Jsoup.parse(body);
            document.outputSettings().prettyPrint(false);
            Elements elements = document.getElementsByTag("img");
            if(elements != null && elements.size() != 0) {
                int size = elements.size();
                for (int i = 0; i < size; i++) {
                    Element element = elements.get(i);
                    String cid = element.attr("src").replace("cid:", "");
                    if (contentIdFileFullPath.containsKey(cid)) {
                        FileFullPathType fileFullPathType = contentIdFileFullPath.get(cid);
                        fileFullPathType.setFileType(FileType.BODY_IMAGE);
                        element.attr("src", fileFullPathType.getFileFullPath());
                    }
                }
                replaceBody = document.outerHtml();
            } else {
                replaceBody = body;
            }
        } else {
            replaceBody = body;
        }

    }

    private static final String TEXT_PLAIN = "text/plain";
    private static final String TEXT_HTML = "text/html";
    private static final String MULTIPART_ALL = "multipart/*";
    private static final String MESSAGE_RFC822 = "message/rfc822";
    private static final String APPLICATION_ALL = "application/*";

    private void multipartContent(Part part, StringBuilder stringBuilder) throws MessagingException, IOException {
        String contentType = part.getContentType();
        int nameIndex = contentType.indexOf("name");
        boolean containName = false;
        if (nameIndex != -1) {
            containName = true;
        }
        if (part.isMimeType(TEXT_PLAIN) && !containName) {
//            stringBuilder.append((String) part.getContent());
            // skip 根据业务,暂时只保存html
        } else if (part.isMimeType(TEXT_HTML) && !containName) {
            stringBuilder.append((String) part.getContent());
        } else if (part.isMimeType(MULTIPART_ALL)) {
            Multipart multipart = (Multipart) part.getContent();
            for (int i = 0, counts = multipart.getCount() ; i < counts; i++) {
                multipartContent(multipart.getBodyPart(i), stringBuilder);
            }
        } else if (part.isMimeType(MESSAGE_RFC822)) {
            multipartContent((Part) part.getContent(), stringBuilder);
        }
    }

    /**
     * 抄送
     */
    public String[] ccs() throws UnsupportedEncodingException, MessagingException {
        if(ccs == null) {
            ccs = assembleToOrCc(Message.RecipientType.CC, ccPersonalMails);
        }
        return ccs;
    }

    /**
     * 接收人(to)或抄送人(cc)中的人或地址类型
     * 原始:chenyunan<chenyunan@banggood.com>
     * personal:chenyunan
     * address:chenyunan@banggood.com
     */
    public enum PersonalMail {
        PERSONAL, ADDRESS;
    }

    /**
     * 获取cc中的人或地址
     */
    public String ccPersonalOrMail(String personalMail, PersonalMail type) {
        switch (type) {
            case PERSONAL:
                return ccPersonalMails.containsKey(personalMail) ? ccPersonalMails.get(personalMail)[0] : null;
            case ADDRESS:
                return ccPersonalMails.containsKey(personalMail) ? ccPersonalMails.get(personalMail)[1] : null;
        }
        return null;
    }

    /**
     * 获取to中的人或地址
     */
    public String toPersonalOrMail(String personalMail, PersonalMail type) {
        switch (type) {
            case PERSONAL:
                return toPersonalMails.containsKey(personalMail) ? toPersonalMails.get(personalMail)[0] : null;
            case ADDRESS:
                return toPersonalMails.containsKey(personalMail) ? toPersonalMails.get(personalMail)[1] : null;
        }
        return null;
    }

    /**
     * 获取接收人
     */
    public String[] tos() throws MessagingException, UnsupportedEncodingException {
        if(tos == null) {
            tos = assembleToOrCc(Message.RecipientType.TO, toPersonalMails);
        }
        return tos;
    }

    /**
     * 获取相应类型(to或cc)数据
     */
    private String[] assembleToOrCc(Message.RecipientType recipientType, Map<String, String[]> map) throws MessagingException, UnsupportedEncodingException {
        InternetAddress address[] = (InternetAddress[]) message.getRecipients(recipientType);
        if (address != null) {
            StringBuilder personalMails = new StringBuilder();
            String[] personalMailArgs;
            for (int i = 0; i < address.length; i++) {
                String personalMail = "";

                String personal = address[i].getPersonal();
                if(personal != null) {
                    personal = MimeUtility.decodeText(personal);
                    personalMail += personal;
                }

                personalMail += "<";

                String email = address[i].getAddress();
                if(email != null) {
                    email = MimeUtility.decodeText(email);
                    personalMail += email;
                }

                personalMail += ">";

                if("<>".equals(personalMail)) {
                    continue;
                } else {
                    personalMailArgs = new String[2];
                    personalMailArgs[0] = personal;
                    personalMailArgs[1] = email;

                    map.put(personalMail, personalMailArgs);

                    personalMails.append(personalMail);
                    personalMails.append(",");
                }
            }

            return personalMails.length() == 0 ?
                    new String[0] : personalMails.substring(0, personalMails.length() - 1).split(",");// size - 1 - ",".length
        } else {
            return new String[0];
        }
    }

    /**
     * 主题,标题
     */
    public String subject() throws MessagingException, UnsupportedEncodingException {
        if(subject == null) {
            subject = MimeUtility.decodeText(message.getSubject());
        }
        return subject;
    }

    /**
     * 发件人
     * 如:chenyunan<chenyunan@banggood.com>
     */
    public String from() throws MessagingException {
        if(from == null) {
            assembleFrom();
        }
        return from;
    }

    /**
     * 发件人,别名
     * 如:chenyunan
     */
    public String fromPersonal() throws MessagingException {
        if(fromPersonal == null) {
            assembleFrom();
        }
        return fromPersonal;
    }

    /**
     * 发件人,邮箱
     * 如:chenyunan@banggood.com
     */
    public String fromMail() throws MessagingException {
        if(fromMail == null) {
            assembleFrom();
        }
        return fromMail;
    }

    private void assembleFrom() throws MessagingException {
        InternetAddress address[] = (InternetAddress[]) message.getFrom();
        fromMail = address[0].getAddress();
        if(fromMail == null) {
            fromMail = "";
        }

        this.fromPersonal = address[0].getPersonal();
        if (fromPersonal == null) {
            fromPersonal = "";
        }

        from = fromPersonal + "<" + fromMail + ">";
    }

}

附件处理类:

package com.test.pojo;

import com.test.common.enums.FileType;
import lombok.Data;

/**
 * @author chenyunan 2018/7/11 10:41
 */
@Data
public class FileFullPathType {

    private String fileFullPath;

    private FileType fileType;

}

邮箱连接协议端口枚举:

package com.test.common.enums;

import lombok.Getter;

/**
 * 邮箱的协议 端口
 * @author chenyunan 2018/6/15 10:22
 */
@Getter
public enum MailProtocol {

    IMAP("imap", 143),
    STMP("stmp", 25),
    IMAPS("imaps", 993),
    STMPS("stmps", 465);

    private String protocol;
    private int port;
    MailProtocol(String protocol, int port) {
        this.protocol = protocol;
        this.port = port;
    }

}

文件流类型(附件或文本图片):

package com.test.common.enums;

/**
 * @author chenyunan 2018/7/11 10:42
 */
public enum FileType {

    // 附件
    ATTACHMENT,
    // 邮件内容中的图片
    BODY_IMAGE;

}

启动类,测试:

package com.test;

import com.sun.mail.imap.IMAPStore;
import com.test.build.IMAPBuilder;
import com.test.common.enums.FileType;
import com.test.common.enums.MailProtocol;
import com.test.domain.MailMessage;
import com.test.pojo.FileFullPathType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chenyunan 2018/7/11 10:28
 */
public class App {

    private static final Logger logger = LoggerFactory.getLogger(App.class);

    private static final String PREFIX_PATH = "d:/tmp/";

    public static void main(String[] args) throws MessagingException, IOException {
        Session session = IMAPBuilder.sessionBuilder(MailProtocol.IMAPS)
                .connectionTimeout(5000)
                .host("imap.exmail.qq.com")
                .username("xxx@qq.com")
                .fetchSize(4)
                .password("123123")
                .build();

        MailMessage mailMessage = null;
        try (Store store = session.getStore()) {
            if (store instanceof IMAPStore) {
                IMAPStore imapStore = (IMAPStore) store;
                imapStore.connect();
                try (Folder folder = imapStore.getFolder("INBOX")){
                    if (folder.exists()) {
                        folder.open(Folder.READ_ONLY);

                        // 邮箱邮件总数
                        int count = folder.getMessageCount();

                        // 邮件指针从1开始
                        // 获取最新一封邮件
                        Message message = folder.getMessage(count);

                        logger.info("------邮件总数:{}", count);
                        logger.info("------邮件标题:{}", message.getSubject());

                        mailMessage = MailMessage.init(message);

                        String from = mailMessage.from();
                        String[] tos = mailMessage.tos();
                        String[] ccs = mailMessage.ccs();

                        logger.info("------发件人:{}", from);
                        logger.info("------发件人别名:{}", mailMessage.fromPersonal());
                        logger.info("------发件人邮箱地址:{}", mailMessage.fromMail());
                        logger.info("------标题:{}", mailMessage.subject());
                        if(tos != null && tos.length != 0) {
                            logger.info("------收件人:{}", tos);
                            logger.info("------第一个收件人别名:{}", mailMessage.toPersonalOrMail(tos[0], MailMessage.PersonalMail.PERSONAL));
                            logger.info("------第一个收件人邮箱地址:{}", mailMessage.toPersonalOrMail(tos[0], MailMessage.PersonalMail.ADDRESS));
                        }
                        if(ccs != null && ccs.length != 0) {
                            logger.info("------抄送人:{}", ccs);
                            logger.info("------第一个抄送人别名:{}", mailMessage.ccPersonalOrMail(ccs[0], MailMessage.PersonalMail.PERSONAL));
                            logger.info("------第一个抄送人邮箱地址:{}", mailMessage.ccPersonalOrMail(ccs[0], MailMessage.PersonalMail.ADDRESS));
                        }
                        logger.info("------类型为:text/html 的正文内容:{}", mailMessage.body());
                        logger.info("------附件:{}", mailMessage.attachments());
                        logger.info("------UUID-FILE-STREAM:{}", mailMessage.srcAttachmentStream());
                        if(mailMessage.srcAttachmentStream() != null) {

                            Map<String, FileFullPathType> contentIdFileFullPath = new HashMap<>();
                            for(String contentId : mailMessage.srcAttachmentStream().rowKeySet()) {
                                FileFullPathType fileFullPathType = new FileFullPathType();
                                mailMessage.srcAttachmentStream().row(contentId).forEach((key, value) -> fileFullPathType.setFileFullPath(PREFIX_PATH + key));
                                fileFullPathType.setFileType(FileType.ATTACHMENT);
                                contentIdFileFullPath.put(contentId, fileFullPathType);

                                // 保存文件
                                Map<String, InputStream> fileNameInputstream = mailMessage.srcAttachmentStream().row(contentId);
                                for(String fileName : fileNameInputstream.keySet()) {
                                    try(InputStream inputStream = fileNameInputstream.get(fileName)) {
                                        File file = new File(PREFIX_PATH + fileName);
                                        if(!file.exists()) {
                                            try {
                                                file.createNewFile();
                                            } catch (IOException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                        byte []bytes = new byte[65536];
                                        try (OutputStream outputStream = new FileOutputStream(file)){
                                            int index;
                                            while((index = inputStream.read(bytes)) != -1) {
                                                outputStream.write(bytes, 0, index);
                                            }
                                        } catch (IOException e) {
                                            logger.error("", e);
                                        } finally {
                                            logger.info("------文件保存,地址:{}", PREFIX_PATH + fileName);
                                        }
                                    }

                                }

                            }
                            // 原始:src="cid:078E8559@BCD85E73.8172455B.jpg"
                            // 替换后:src="d:/tmp/078E8559@BCD85E73.8172455B.jpg"
                            logger.info("------替换src标签内容之后的内容:{}", mailMessage.replaceBody(contentIdFileFullPath));
                        }
                    }
                }
            }
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }
}

输出结果:

16:45:07.689 [main] INFO  com.test.App - ------邮件总数:1431
16:45:08.048 [main] INFO  com.test.App - ------邮件标题:这是一封测试邮件
16:45:08.050 [main] INFO  com.test.App - ------发件人:chenyunan@banggood.com<chenyunan@banggood.com>
16:45:08.050 [main] INFO  com.test.App - ------发件人别名:chenyunan@banggood.com
16:45:08.050 [main] INFO  com.test.App - ------发件人邮箱地址:chenyunan@banggood.com
16:45:08.050 [main] INFO  com.test.App - ------标题:这是一封测试邮件
16:45:08.050 [main] INFO  com.test.App - ------收件人:chenyunan<chenyunan@banggood.com>
16:45:08.051 [main] INFO  com.test.App - ------第一个收件人别名:chenyunan
16:45:08.051 [main] INFO  com.test.App - ------第一个收件人邮箱地址:chenyunan@banggood.com
16:45:08.051 [main] INFO  com.test.App - ------抄送人:chenyunan<chenyunan@banggood.com>
16:45:08.051 [main] INFO  com.test.App - ------第一个抄送人别名:chenyunan
16:45:08.051 [main] INFO  com.test.App - ------第一个抄送人邮箱地址:chenyunan@banggood.com
16:45:08.648 [main] INFO  com.test.App - ------类型为:text/html 的正文内容:<html><head><meta http-equiv="content-type" content="text/html; charset=GB2312"><style>body { line-height: 1.5; }blockquote { margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em; }div.foxdiv20180711160907014546 { }body { font-size: 10.5pt; font-family: 微软雅黑; color: rgb(0, 0, 0); line-height: 1.5; }</style></head><body>
<div><span></span><br></div><blockquote style="margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em;"><div><div class="FoxDiv20180711160907014546"><blockquote style="margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em;"><div><div class="FoxDiv20180711160207551816">
<div><span></span>里边的内容是这些<img src="cid:_Foxmail.1@c2779f19-e831-7609-db30-d579df91f1cb" border="0" style="font-size: 10.5pt; line-height: 1.5; background-color: window;"><img src="cid:_Foxmail.1@093484e4-2c8c-7869-d22c-323baeffcda2" border="0" style="font-size: 10.5pt; line-height: 1.5; background-color: window;"></div>
<div><br></div><hr style="width: 210px; height: 1px;" color="#b5c4df" size="1" align="left">
<div><span><div style="MARGIN: 10px; FONT-FAMILY: verdana; FONT-SIZE: 10pt"><div>chenyunan@banggood.com</div></div></span></div>
</div></div></blockquote>
</div></div></blockquote>
</body></html>
16:45:09.455 [main] INFO  com.test.App - ------附件:InsertPic_(07-11(07-11-16-09-0
16:45:09.462 [main] INFO  com.test.App - ------UUID-FILE-STREAM:{_Foxmail.1@c2779f19-e831-7609-db30-d579df91f1cb={InsertPic_(07-11(07-11-16-09-0=com.sun.mail.util.BASE64DecoderStream@3098cf3b}, _Foxmail.1@093484e4-2c8c-7869-d22c-323baeffcda2={Catch(07-11-16-0(07-11-16-09-0=com.sun.mail.util.BASE64DecoderStream@610f7aa}, xxx.xls={xxx.xls=com.sun.mail.util.BASE64DecoderStream@6a03bcb1}}
16:45:09.770 [main] INFO  com.test.App - ------文件保存,地址:d:/tmp/InsertPic_(07-11(07-11-16-09-0
16:45:10.062 [main] INFO  com.test.App - ------文件保存,地址:d:/tmp/Catch(07-11-16-0(07-11-16-09-0
16:45:10.342 [main] INFO  com.test.App - ------文件保存,地址:d:/tmp/xxx.xls
16:45:10.392 [main] INFO  com.test.App - ------替换src标签内容之后的内容:<html><head><meta http-equiv="content-type" content="text/html; charset=GB2312"><style>body { line-height: 1.5; }blockquote { margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em; }div.foxdiv20180711160907014546 { }body { font-size: 10.5pt; font-family: 微软雅黑; color: rgb(0, 0, 0); line-height: 1.5; }</style></head><body>
<div><span></span><br></div><blockquote style="margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em;"><div><div class="FoxDiv20180711160907014546"><blockquote style="margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em;"><div><div class="FoxDiv20180711160207551816">
<div><span></span>里边的内容是这些<img src="d:/tmp/InsertPic_(07-11(07-11-16-09-0" border="0" style="font-size: 10.5pt; line-height: 1.5; background-color: window;"><img src="d:/tmp/Catch(07-11-16-0(07-11-16-09-0" border="0" style="font-size: 10.5pt; line-height: 1.5; background-color: window;"></div>
<div><br></div><hr style="width: 210px; height: 1px;" color="#b5c4df" size="1" align="left">
<div><span><div style="MARGIN: 10px; FONT-FAMILY: verdana; FONT-SIZE: 10pt"><div>chenyunan@banggood.com</div></div></span></div>
</div></div></blockquote>
</div></div></blockquote>
</body></html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值