springboot发邮件,javaxmail收邮件功能

简介: springboot发邮件,javaxmail收邮件功能


import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.protocol.IMAPProtocol;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.util.ObjectUtils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class ReceivedIMAPMail {

public static String NORM_DATETIME_PATTERN = "yyyy-MM-dd hh:mm:ss";

private MimeMessage mimeMessage;
/**
 * 附件下载后的存放目录
 */
private String saveAttachPath = "";
/**
 * 存放邮件内容的StringBuffer对象
 */
private StringBuffer bodyText = new StringBuffer();

/**
 * 构造函数,初始化一个MimeMessage对象
 *
 * @param mimeMessage
 */
public ReceivedIMAPMail(MimeMessage mimeMessage) {
    this.mimeMessage = mimeMessage;
}

/**
 * 获得发件人的地址和姓名
 *
 * @return
 * @throws MessagingException
 */
public String getFrom() throws MessagingException {
    InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
    String from = address[0].getAddress();
    if (from == null) {
        from = "";
    }
    String personal = address[0].getPersonal();

    if (personal == null) {
        personal = "";
    }

    String fromAddr = null;
    if (personal != null || from != null) {
        fromAddr = personal + "<" + from + ">";
    }
    return fromAddr;
}

/**
 * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同
 *
 * @param type "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
 * @return
 * @throws MessagingException
 * @throws UnsupportedEncodingException
 */
public String getMailAddress(String type) throws MessagingException, UnsupportedEncodingException {
    if (ObjectUtils.isEmpty(type)) {
        return "";
    }

    String addType = type.toUpperCase();

    if (!addType.equals("TO") && !addType.equals("CC") && !addType.equals("BCC")) {
        return "";
    }
    InternetAddress[] address;

    if (addType.equals("TO")) {
        address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.TO);
    } else if (addType.equals("CC")) {
        address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.CC);
    } else {
        address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.BCC);
    }

    if (ObjectUtils.isEmpty(address)) {
        return "";
    }
    StringBuilder mailAddr = new StringBuilder();
    String emailAddr;
    String personal;
    for (int i = 0; i < address.length; i++) {
        emailAddr = address[i].getAddress();
        if (emailAddr == null) {
            emailAddr = "";
        } else {
            emailAddr = MimeUtility.decodeText(emailAddr);
        }
        personal = address[i].getPersonal();
        if (personal == null) {
            personal = "";
        } else {
            personal = MimeUtility.decodeText(personal);
        }
        mailAddr.append(",").append(personal).append("<").append(emailAddr).append(">");
    }
    return mailAddr.toString().substring(1);
}

/**
 * 获得邮件主题
 *
 * @return
 * @throws MessagingException
 * @throws UnsupportedEncodingException
 */
public String getSubject() throws MessagingException, UnsupportedEncodingException {
    String subject = MimeUtility.decodeText(mimeMessage.getSubject());
    if (subject == null) {
        subject = "";
    }
    return subject;
}

/**
 * 获得邮件发送日期
 *
 * @return
 * @throws MessagingException
 */
public String getSentDate() throws MessagingException {
    Date sentDate = mimeMessage.getSentDate();
    SimpleDateFormat format = new SimpleDateFormat(NORM_DATETIME_PATTERN);
    return format.format(sentDate);
}

/**
 * 获得邮件正文内容
 *
 * @return
 */
public String getBodyText() {
    return bodyText.toString();
}

/**
 * 解析邮件,把得到的邮件内容保存到一个StringBuffer对象中,解析邮件 主要是根据MimeType类型的不同执行不同的操作,一步一步的解析
 * 
 * @param part
 * @throws MessagingException
 * @throws IOException
 */
public void getMailContent(Part part) throws MessagingException, IOException {

    String contentType = part.getContentType();

    int nameIndex = contentType.indexOf("name");

    boolean conName = false;

    if (nameIndex != -1) {
        conName = true;
    }

    if (part.isMimeType("text/plain") && conName == false) {
        bodyText.append((String) part.getContent());
    } else if (part.isMimeType("text/html") && conName == false) {
        bodyText.append((String) part.getContent());
    } else if (part.isMimeType("multipart/*")) {
        Multipart multipart = (Multipart) part.getContent();
        int counts = multipart.getCount();
        for (int i = 0; i < counts; i++) {
            this.getMailContent(multipart.getBodyPart(i));
        }
    } else if (part.isMimeType("message/rfc822")) {
        this.getMailContent((Part) part.getContent());
    }
}

/**
 * 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false"
 *
 * @return
 * @throws MessagingException
 */
public boolean getReplySign() throws MessagingException {

    boolean replySign = false;

    String needReply[] = mimeMessage.getHeader("Disposition-Notification-To");

    if (needReply != null) {
        replySign = true;
    }
    return replySign;
}

/**
 * 判断此邮件是否已读,如果未读返回false,反之返回true
 *
 * @return
 * @throws MessagingException
 */
public boolean isNew() throws MessagingException {
    boolean isNew = false;
    Flags flags = mimeMessage.getFlags();
    Flags.Flag[] flag = flags.getSystemFlags();
    for (int i = 0; i < flag.length; i++) {
        if (flag[i] == Flags.Flag.SEEN) {
            isNew = true;
        }
    }
    return isNew;
}

/**
 * 判断此邮件是否包含附件
 *
 * @param part
 * @return
 * @throws MessagingException
 * @throws IOException
 */
public boolean isContainAttach(Part part) throws MessagingException, IOException {
    boolean attachFlag = false;
    if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        BodyPart mPart;
        String conType;
        for (int i = 0; i < mp.getCount(); i++) {
            mPart = mp.getBodyPart(i);
            String disposition = mPart.getDisposition();
            if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
                attachFlag = true;
            } else if (mPart.isMimeType("multipart/*")) {
                attachFlag = this.isContainAttach(mPart);
            } else {
                conType = mPart.getContentType();
                if (conType.toLowerCase().indexOf("application") != -1
                        || conType.toLowerCase().indexOf("name") != -1) {
                    attachFlag = true;
                }
            }
        }
    } else if (part.isMimeType("message/rfc822")) {
        attachFlag = isContainAttach((Part) part.getContent());
    }
    return attachFlag;
}

/**
 * 保存附件
 *
 * @param part
 * @throws MessagingException
 * @throws IOException
 */
public void saveAttachMent(Part part) throws MessagingException, IOException {
    String fileName;
    if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        BodyPart mPart;
        for (int i = 0; i < mp.getCount(); i++) {
            mPart = mp.getBodyPart(i);
            String disposition = mPart.getDisposition();
            if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
                fileName = mPart.getFileName();
                if (null != fileName && fileName.toLowerCase().indexOf("gb2312") != -1) {
                    fileName = MimeUtility.decodeText(fileName);
                }
                fileName = fileName.replaceAll("\\?|=", "");
                this.saveFile(fileName, mPart.getInputStream());
            } else if (mPart.isMimeType("multipart/*")) {
                this.saveAttachMent(mPart);
            } else {
                fileName = mPart.getFileName();
                if ((fileName != null) && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                    fileName = MimeUtility.decodeText(fileName);
                    this.saveFile(fileName, mPart.getInputStream());
                }
            }
        }
    } else if (part.isMimeType("message/rfc822")) {
        this.saveAttachMent((Part) part.getContent());
    }
}

/**
 * 设置附件存放路径
 *
 * @param attachPath
 */
public void setAttachPath(String attachPath) {
    this.saveAttachPath = attachPath;
}

/**
 * 获得附件存放路径
 *
 * @return
 */
public String getAttachPath() {
    return saveAttachPath;
}

/**
 * 真正的保存附件到指定目录里
 *
 * @param fileName
 * @param in
 * @throws IOException
 */
private void saveFile(String fileName, InputStream in) throws IOException {
    String osName = System.getProperty("os.name");
    String storeDir = this.getAttachPath();
    if (null == osName) {
        osName = "";
    }
    if (osName.toLowerCase().indexOf("win") != -1) {
        if (ObjectUtils.isEmpty(storeDir))
            storeDir = "C:\\tmp";
    } else {
        storeDir = "/tmp";
    }
    FileOutputStream fos = new FileOutputStream(new File(storeDir + File.separator + fileName));
    IOUtils.copy(in, fos);
    IOUtils.closeQuietly(fos);
    IOUtils.closeQuietly(in);
}

/**
 * 获取阿里云邮箱信息
 *
 * @param host     邮件服务器
 * @param username 邮箱名
 * @param password 密码
 * @param protocol 协议
 * @return
 * @throws MessagingException
 */
public static Message[] getALiYunMessage(String host, String username, String password, String protocol)
        throws MessagingException {
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);

    Store store = session.getStore(protocol);
    store.connect(host, username, password);

    Folder folder = store.getFolder("INBOX");
    folder.open(Folder.READ_ONLY);
    return folder.getMessages();
}

/**
 * 获取163邮箱信息
 *
 * @param host
 * @param username
 * @param password
 * @param protocol
 * @return
 * @throws MessagingException
 */
public static Message[] getWEMessage(String host, String username, String password, String protocol)
        throws MessagingException {
    Properties props = System.getProperties();
    props.setProperty("mail.store.protocol", protocol);
    Session session = Session.getDefaultInstance(props, null);
    Store store = session.getStore(protocol);
    store.connect(host, username, password);
    Folder folder = store.getFolder("INBOX");

    if (folder instanceof IMAPFolder) {
        IMAPFolder imapFolder = (IMAPFolder) folder;
        // javamail中使用id命令有校验checkOpened, 所以要去掉id方法中的checkOpened();
        imapFolder.doCommand(new IMAPFolder.ProtocolCommand() {
            public Object doCommand(IMAPProtocol p) throws com.sun.mail.iap.ProtocolException {
                Map<String, String> gmap = new HashMap<>();
                gmap.put("GUID", "FUTONG");
                // p.id("FUTONG");
                p.id(gmap);
                return null;
            }
        });
    }

    if (folder != null) {
        folder.open(Folder.READ_WRITE);
    }

    return folder.getMessages();
}

/**
 * 过滤邮箱信息
 *
 * @param messages
 * @param fromMail  只读取该邮箱发来的邮件,如果为空则不过滤
 * @param startDate 只读取该日期以后的邮件,如果为空则不过滤
 * @return
 * @throws MessagingException
 */
public static List<Message> filterMessage(Message[] messages, String fromMail, String startDate)
        throws MessagingException, ParseException {
    List<Message> messageList = new ArrayList<>();
    if (ObjectUtils.isEmpty(messages)) {
        return messageList;
    }
    boolean isEnptyFromMail = ObjectUtils.isEmpty(fromMail);
    boolean isEnptyStartDate = ObjectUtils.isEmpty(startDate);
    if (isEnptyFromMail && isEnptyStartDate) {
        return Arrays.asList(messages);
    }

    String from;
    for (Message message : messages) {
        from = (message.getFrom()[0]).toString();
        if (isEnptyFromMail) {
            if (new SimpleDateFormat(NORM_DATETIME_PATTERN).parse(startDate).getTime() > message.getSentDate()
                    .getTime()) {
                continue;
            }
        } else if (null != from && from.contains(fromMail)) {
            if (!isEnptyStartDate && new SimpleDateFormat(NORM_DATETIME_PATTERN).parse(startDate)
                    .getTime() > message.getSentDate().getTime()) {
                continue;
            }
        } else {
            continue;
        }
        messageList.add(message);
    }
    return messageList;
}

/**
 * 打印邮件
 *
 * @param messageList
 * @throws IOException
 * @throws MessagingException
 */
public static void printMailMessage(List<Message> messageList) throws IOException, MessagingException {
    System.out.println("邮件数量:" + messageList.size());
    ReceivedIMAPMail re;
    Message message;
    for (int i = 0, leng = messageList.size(); i < leng; i++) {
        message = messageList.get(i);
        re = new ReceivedIMAPMail((MimeMessage) message);
        System.out.println("邮件【" + i + "】主题:" + re.getSubject());
        System.out.println("邮件【" + i + "】发送时间:" + re.getSentDate());
        System.out.println("邮件【" + i + "】是否需要回复:" + re.getReplySign());
        System.out.println("邮件【" + i + "】是否已读:" + re.isNew());
        System.out.println("邮件【" + i + "】是否包含附件:" + re.isContainAttach(message));
        System.out.println("邮件【" + i + "】发送人地址:" + re.getFrom());
        System.out.println("邮件【" + i + "】收信人地址:" + re.getMailAddress("to"));
        System.out.println("邮件【" + i + "】抄送:" + re.getMailAddress("cc"));
        System.out.println("邮件【" + i + "】暗抄:" + re.getMailAddress("bcc"));
        System.out.println("邮件【" + i + "】发送时间:" + re.getSentDate());
        System.out.println("邮件【" + i + "】邮件ID:" + ((MimeMessage) message).getMessageID());
        re.getMailContent(message);
        // System.out.println("邮件【" + i + "】正文内容:\r\n" + re.getBodyText());
        if(re.isContainAttach(message)) {
            System.out.println("邮件包含附件,开始下载到D:\\xl下面");
            re.setAttachPath("D:\\xl\\mail\\");
            re.saveAttachMent(message);
        }
    }
}

public static void main(String[] args) throws MessagingException, IOException, ParseException {
    // 阿里云登录信息

// String host = "pop3.mxhichina.com";
// String username = "liwei@xiaostudy.com";
// String password = "密码";
// String protocol = "pop3";
// String fromMail = "XXX@163.com";
// String startDate = "2020-2-24 23:35:40";
// List messageList = filterMessage(getALiYunMessage(host, username, password, protocol), fromMail, startDate);

    // 163登录信息
    String host = "imap.163.com";
    String username = "*****@163.com";
    String password = "客户端授权码";
    String protocol = "imaps";
    String fromMail = "";// "****@163.com";
    String startDate = "";// "2020-2-24 23:35:40";
    List<Message> messageList = filterMessage(getWEMessage(host, username, password, protocol), fromMail,
            startDate);

    printMailMessage(messageList);
}

}

相关文章
|
3月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
525 2
|
9月前
|
XML 前端开发 Java
SpringBoot实现文件上传下载功能
本文介绍了如何使用SpringBoot实现文件上传与下载功能,涵盖配置和代码实现。包括Maven依赖配置(如`spring-boot-starter-web`和`spring-boot-starter-thymeleaf`)、前端HTML页面设计、WebConfig路径映射配置、YAML文件路径设置,以及核心的文件上传(通过`MultipartFile`处理)和下载(利用`ResponseEntity`返回文件流)功能的Java代码实现。文章由Colorful_WP撰写,内容详实,适合开发者学习参考。
947 0
|
6月前
|
缓存 前端开发 Java
SpringBoot 实现动态菜单功能完整指南
本文介绍了一个动态菜单系统的实现方案,涵盖数据库设计、SpringBoot后端实现、Vue前端展示及权限控制等内容,适用于中后台系统的权限管理。
707 1
|
8月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
1126 8
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
264 0
|
7月前
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
1528 0
|
9月前
|
SQL 前端开发 Java
深入理解 Spring Boot 项目中的分页与排序功能
本文深入讲解了在Spring Boot项目中实现分页与排序功能的完整流程。通过实际案例,从Service层接口设计到Mapper层SQL动态生成,再到Controller层参数传递及前端页面交互,逐一剖析每个环节的核心逻辑与实现细节。重点包括分页计算、排序参数校验、动态SQL处理以及前后端联动,确保数据展示高效且安全。适合希望掌握分页排序实现原理的开发者参考学习。
644 4
|
9月前
|
存储 Java 定位技术
SpringBoot整合高德地图完成天气预报功能
本文介绍了如何在SpringBoot项目中整合高德地图API实现天气预报功能。从创建SpringBoot项目、配置依赖和申请高德地图API开始,详细讲解了实体类设计、服务层实现(调用高德地图API获取实时与预报天气数据)、控制器层接口开发以及定时任务的设置。通过示例代码,展示了如何获取并处理天气数据,最终提供实时天气与未来几天天气预报的接口。文章还提供了测试方法及运行步骤,帮助开发者快速上手并扩展功能。
|
消息中间件 缓存 Java
手写模拟Spring Boot启动过程功能
【11月更文挑战第19天】Spring Boot自推出以来,因其简化了Spring应用的初始搭建和开发过程,迅速成为Java企业级应用开发的首选框架之一。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,帮助读者深入理解其工作机制。
195 3

热门文章

最新文章