java从腾讯邮箱获得文件

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: java从腾讯邮箱获得文件
package com.jack.platformweb.email.service;
import com.sun.mail.imap.IMAPStore;
import com.jack.common.redis.service.RedisService;
import com.jack.common.utils.DateUtils;
import com.jack.common.utils.JsonUtils;
import com.jack.common.utils.ZipUtils;
import com.jack.db.urgerobot.robot.model.RobotInfo;
import com.jack.platformweb.partner.service.GzOutUrgeFileService;
import com.jack.platformweb.robot.service.RobotInfoService;
import net.lingala.zip4j.exception.ZipException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import javax.print.DocFlavor;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * @Description
 * @Author zhenghao
 * @Date 2021/8/17 22:07
 **/
@Service
public class RemoteEmailService {
    private static Logger log = LoggerFactory.getLogger(RemoteEmailService.class);
    @Value("${gz.local.path}")
    private String attachFilePath;
    @Autowired
    private GzOutUrgeFileService gzOutUrgeFileService;
    @Autowired
    private RobotInfoService robotInfoService;
    @Autowired
    private RedisService redisService;
    //从哪个邮箱地址获取内容
    private static String username = "test@qq.com";
    private static String password = "123456";
    private static Integer robotId = 161;
    //过滤发件人
    private static List<String> monitoringEmail = Stream.of("tt@qq.com").collect(Collectors.toList());
    private IMAPStore getConnect() {
        log.info("开始获得邮件链接");
        // 准备连接服务器的会话信息
        IMAPStore store = null;
        try {
            Properties props = new Properties();
//            props.setProperty("mail.store.protocol", "imap");
//            props.setProperty("mail.imap.host", "imap.exmail.qq.com");
//            props.setProperty("mail.imap.port", "993");
//            props.setProperty("mail.imap.ssl.enable", "true");
//
//            props.setProperty("mail.imap.auth.plain.disable", "true");
//
//            Session session = Session.getInstance(props, new javax.mail.Authenticator() {
//                @Override
//
//                protected PasswordAuthentication getPasswordAuthentication() {
//                    return new PasswordAuthentication(username, password
//
//                    );
//
//                }
//
//            });
            props.put("mail.imap.host", "imap.exmail.qq.com");//QQ邮箱为:imap.qq.com
            props.put("mail.imap.auth", "true");
            props.setProperty("mail.store.protocol", "imap");
            props.put("mail.imap.starttls.enable", "true");
            Session session = Session.getInstance(props);
//            // 创建Session实例对象
//            Session session = Session.getInstance(props);
            // 创建IMAP协议的Store对象
            store = (IMAPStore) session.getStore("imap");
            // 连接邮件服务器
            store.connect("imap.exmail.qq.com", username, password);
        } catch (Exception e) {
            log.info("成功获得邮件链接失败");
            e.printStackTrace();
        }
        log.info("成功获得邮件链接");
        return store;
    }
    public boolean receiveEmail() {
        log.info("开始执行远程获得邮件任务");
        try {
            String key = "remoteEmailkey" + DateUtils.getToDayStartYYMMMDD();
            String s = redisService.get(key);
            if (StringUtils.isNotEmpty(s)) {
                log.info("远程获得邮件已经成功执行");
                return false;
            }
            /**
             * 1. 取得链接
             */
            IMAPStore imapStore = getConnect();
            if (null == imapStore) {
                log.error("获取邮箱imap连接失败。方法执行失败。退出当前方法!!!!!!!");
                return false;
            }
            Folder defaultFolder = imapStore.getDefaultFolder();
            if (defaultFolder == null) {
                log.info("服务器不可用");
                return false;
            }
            Folder folder = imapStore.getFolder("INBOX");
            folder.open(Folder.READ_WRITE);
            //获得所有近30天的邮件,近30天是在客户端配置的
            Message[] messages = folder.getMessages();
//        Message[] messages = folder.getMessages(folder.getMessageCount() - folder.getUnreadMessageCount() + 1, folder.getMessageCount());
            log.info("未读邮件数量: {}", messages.length);
            for (Message msg : messages) {
                try {
                    //邮件发送日期超过两天 退出遍历方法
                    if (!outDays(msg)) {
                        log.info("邮件{}已过期,退出循环", msg.getSubject());
                        continue;
                    }
                    //不是最新邮件,跳过
                    //                if (isNew(msg)) {
                    //                    log.info("邮件不是新邮件,跳过");
                    //                    continue;
                    //                }
                    //是否属于需要处理的邮件
                    if (needProcessEmail(msg)) {
                        redisService.setex(key, 20 * 60 * 60, "1");
                        break;
                    } else {
                        log.info("邮件不需要处理,跳过");
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
            //关闭资源
            folder.close(true);
            imapStore.close();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * @param
     * @param msg
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 检查当前邮件是否已超过1天, 接收时间大于1天以前 返回true
     */
    private boolean outDays(Message msg) {
        String s = "";
        Date receiveDate = null;
        try {
            receiveDate = msg.getReceivedDate();
            s = DateUtils.formatYYYYMMDD(receiveDate);
            log.info("邮件接收时间:{}", DateUtils.formatYYYYMMDD(receiveDate));
            return DateUtils.getToDayYYYYMMDD().equals(s);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return true;
    }
    /**
     * @param
     * @param msg
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 判断邮件是否是新的邮件
     */
    private boolean isNew(Message msg) throws MessagingException {
        boolean isNewFlag = false;
        Flags flags = msg.getFlags();
        Flags.Flag[] flagsArr = flags.getSystemFlags();
        log.info("邮件状态:" + JsonUtils.writeValue(flagsArr));
        for (Flags.Flag flag : flagsArr) {
            if (flag == Flags.Flag.SEEN) {
                isNewFlag = true;
                log.info("当前邮件为未读状态!");
                break;
            }
        }
        return isNewFlag;
    }
    /**
     * @param
     * @param msg
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 检查邮件内容是否需要我们处理
     * 1. 检查发件人是否满足要求
     * 2. 检查是否包含附件
     * 3. 检查是否有满足条件的附件
     */
    private boolean needProcessEmail(Message msg) throws Exception {
        log.info("needProcessEmail  > 当前邮件的标题:{}", msg.getSubject());
        // 1. 检查发件人邮箱是否包含在我们监控的邮箱列表里面
        String from = getFrom(msg);
        if (!monitoringEmail.contains(from)) {
            log.info("当前邮件的发件人[{}]不是我们要监控的对象", from);
            return false;
        }
        if (!isContainAttach((Part) msg)) {
            log.info("发件人满足要求但是附件为空,不满足我们监控的需求!");
            return false;
        }
        Map<String, InputStream> fileMap = new HashMap<>();
        getFileInputStream(msg, fileMap);
        if (fileMap.isEmpty()) {
            log.info("尽管邮件中有附件但是邮件中的附件却无一个满足要求!");
            return false;
        } else {
            //写入本地文件
            for (String s : fileMap.keySet()) {
                InputStream inputStream = fileMap.get(s);
                this.getFile(inputStream, attachFilePath + "/" + s);
                this.dealFileData(attachFilePath + "/" + s);
                break;
            }
        }
        return true;
    }
    /**
     * @param
     * @param part
     * @return java.io.InputStream
     * @author FeianLing
     * @date 2019/8/20
     * @desc 获取文件输入流
     */
    private void getFileInputStream(Part part, Map<String, InputStream> inputStreamMap) throws Exception {
        String fileName;
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    fileName = mPart.getFileName();
                    fileName = MimeUtility.decodeText(fileName);
                    if (checkFileName(fileName)) {
                        inputStreamMap.put(fileName, mPart.getInputStream());
                    }
                } else if (mPart.isMimeType("multipart/*")) {
                    log.info("子邮件里面的附件");
                    getFileInputStream(mPart, inputStreamMap);
                } else {
                    fileName = mPart.getFileName();
                    if ((fileName != null)
                            && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                        fileName = MimeUtility.decodeText(fileName);
                        if (checkFileName(fileName)) {
                            inputStreamMap.put(fileName, mPart.getInputStream());
                        }
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            getFileInputStream((Part) part.getContent(), inputStreamMap);
        }
    }
    /**
     * @param
     * @param fileName
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 检查文件名称是否符合要求 AI智能语音催收名单——智清厂商-0803.xls
     */
    private boolean checkFileName(String fileName) {
        return (fileName.contains("AI外呼剔除名单") || fileName.contains("AI外呼提出名单"));
    }
    /**
     * @param
     * @param part
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 判断邮件是否包含附件,如果没有包含附件,返回false 反之返回true
     */
    private boolean isContainAttach(Part part) throws Exception {
        boolean attachFlag = false;
        // String contentType = part.getContentType();
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    attachFlag = true;
                } else if (mPart.isMimeType("multipart/*")) {
                    attachFlag = isContainAttach((Part) mPart);
                } else {
                    String conType = mPart.getContentType();
                    if (conType.toLowerCase().indexOf("application") != -1) {
                        attachFlag = true;
                    }
                    if (conType.toLowerCase().indexOf("name") != -1) {
                        attachFlag = true;
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachFlag = isContainAttach((Part) part.getContent());
        }
        return attachFlag;
    }
    /**
     * @param
     * @param msg
     * @return java.lang.String
     * @author FeianLing
     * @date 2019/8/20
     * @desc 获取发送地址
     */
    private String getFrom(Message msg) throws MessagingException {
        String from = "";
        InternetAddress[] addresses = (InternetAddress[]) msg.getFrom();
        if (null == addresses || addresses.length == 0) {
            log.error("无法获取发送人地址信息!");
            return from;
        }
        Address address = addresses[0];
        log.info("发件人地址json:" + JsonUtils.writeValue(address));
        String form = ((InternetAddress) address).getAddress();
        return form;
    }
    public void getFile(InputStream is, String fileName) {
        try {
            BufferedInputStream in = null;
            BufferedOutputStream out = null;
            in = new BufferedInputStream(is);
            out = new BufferedOutputStream(new FileOutputStream(fileName));
            int len = -1;
            byte[] b = new byte[1024];
            while ((len = in.read(b)) != -1) {
                out.write(b, 0, len);
            }
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //业务处理方法
    public void dealFileData(String filePath) {
        try {
            log.info("开始处理文件:" + filePath);
            File file = new File(filePath);
            String name = file.getName();
            String fileName = name.replace(".zip", ".xls");
            ZipUtils.unZip(file, attachFilePath, "111111");
            RobotInfo robotInfoById = robotInfoService.getRobotInfoById(robotId);
            String tempFilePath = attachFilePath + "/" + fileName;
            log.info("处理文件路径:" + tempFilePath);
            gzOutUrgeFileService.autoOutUrge(robotInfoById, tempFilePath);
            log.info("出催文件处理完毕");
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
    }
}
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
6天前
|
分布式计算 DataWorks Java
DataWorks操作报错合集之在使用MaxCompute的Java SDK创建函数时,出现找不到文件资源的情况,是BUG吗
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
22 0
|
28天前
|
存储 缓存 安全
Java 中 IO 流、File文件
Java 中 IO 流、File文件
|
2月前
|
前端开发 Java
Java压缩20M文件非常厉害
Java压缩20M文件非常厉害
27 1
|
2月前
|
Java BI API
Java如何实现文件批量导入导出(兼容xls,xlsx)
Java如何实现文件批量导入导出(兼容xls,xlsx)
42 0
|
2月前
|
Java
有关Java发送邮件信息(支持附件、html文件模板发送)
有关Java发送邮件信息(支持附件、html文件模板发送)
37 1
|
2月前
|
Java
java中替换文件内容
java中替换文件内容
15 1
|
11天前
|
Java Unix Windows
|
15天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
50 3
|
3天前
|
Oracle Java 关系型数据库
windows 下 win11 JDK17安装与环境变量的配置(配置简单详细,包含IJ中java文件如何使用命令运行)
本文介绍了Windows 11中安装JDK 17的步骤,包括从官方网站下载JDK、配置环境变量以及验证安装是否成功。首先,下载JDK 17的安装文件,如果没有Oracle账户,可以直接解压缩文件到指定目录。接着,配置系统环境变量,新建`JAVA_HOME`变量指向JDK安装路径,并在`Path`变量中添加。然后,通过命令行(cmd)验证安装,分别输入`java -version`和`javac -version`检查版本信息。最后,作者分享了如何在任意位置运行Java代码,包括在IntelliJ IDEA(IJ)中创建的Java文件,只需去掉包声明,就可以通过命令行直接运行。
25 0
|
5天前
|
存储 监控 Java
如何在Java中实现等待文件修改后再读取数据的功能?
如何在Java中实现等待文件修改后再读取数据的功能?
11 0