Java获取邮件内容(主要是附件下载 )

3,954 阅读2分钟

       需求:客户不定期将数据以excle文件发送到我司企业邮箱,我们要做的是用定时任务从邮箱拿到数据存到数据库,实现数据对接。

       问题:在现在常用的两种协议pop3和imap中,都不符合开发:

  • pop3协议没有办法判断邮件是否已读,如果使用pop3,每次都拿到全部数据,导致数据重复。常见的解决方法就是,每个邮件服务器会给每个邮件设置一个唯一的uid,客户端将这个uid保存,用来判断是不是已读,这也是现在常见客户端如firefox使用pop3的办法。
  • imap协议可以判断和设置邮件已读,但是他读取邮件的速度非常慢,如果附件的占的储存比较大,会需要非常久的时间才能见附件下载下来(亲测1.5M 大小的文件,下载了5分钟)

因为暂时没有找到更好的方法,所以只能使用者两种,而根据需求,客户发来的数据不会很大,所以使用imap协议

    • 获取邮件的信息

public static void downLoadDate(String file) throws Exception {
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", protocol);
        props.setProperty("mail.imap.host", host);
        Session session = Session.getDefaultInstance(props);
        Store store = session.getStore(protocol);
        store.connect(account, password);
        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        // 全部邮件数
        Message[] messages = folder.getMessages();
        for (int i = 0; i < messages.length; i++) {
            Message message = messages[i];
            // 如果是未读邮件,就下载下来,并设置为已读
            Flags flags = message.getFlags();
            System.out.println(flags.contains(Flags.Flag.SEEN));
            System.out.println(Flags.Flag.SEEN);
            if (flags.contains(Flags.Flag.SEEN)){
                System.out.println("这是一封已读邮件");
            } else {
                System.out.println("未读邮件");
                saveAttachment(message, file); //保存附件
                message.setFlag(Flags.Flag.SEEN, true);
            }

            // 删除邮件
            // message.setFlag(Flags.Flag.DELETED, true);
            // 标记为已读
            //pop3没有判断邮件是否为已读的功能,要使用Imap才可以
                /*Flags flags = message.getFlags();
                if (flags.contains(Flags.Flag.SEEN))
                    System.out.println("这是一封已读邮件");
                else {
                    System.out.println("未读邮件");
                    message.setFlag(Flags.Flag.SEEN, true);
                }*/

            //获取所有的Header,头信息
            //  Enumeration headers = message.getAllHeaders();
            // System.out.println("----------------------allHeaders-----------------------------");
            /*  while (headers.hasMoreElements()) {
                    Header header = (Header)headers.nextElement();
                    System.out.println(header.getName()+" ======= "+header.getValue());
                }*/
            /*
            //解析邮件内容
            Object content = message.getContent();
            if (content instanceof MimeMultipart) {
                MimeMultipart multipart = (MimeMultipart) content;
                parseMultipart(multipart);
            }
            System.out
                    .println("========================================================");
            System.out
                    .println("========================================================");*/

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

    • 保存附件,需要解码

    /**
     * 保存附件
     */
    public static void saveAttachment(Part part, String destDir) throws Exception {
        if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();    //复杂体邮件
            //复杂体邮件包含多个邮件体
            int partCount = multipart.getCount();
            for (int i = 0; i < partCount; i++) {
                //获得复杂体邮件中其中一个邮件体
                BodyPart bodyPart = multipart.getBodyPart(i);
                //某一个邮件体也有可能是由多个邮件体组成的复杂体
                String disp = bodyPart.getDisposition();
                if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {
                    InputStream is = bodyPart.getInputStream();

                    saveFile(is, 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);
        }
    }

    /**
     * 保存文件
     */
    private static void saveFile(InputStream is, String destDir, String fileName) throws Exception {
        BufferedInputStream bis = new BufferedInputStream(is);
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(new File(destDir + fileName)));
        int len = -1;
        while ((len = bis.read()) != -1) {
            bos.write(len);
            bos.flush();
        }
        bos.close();
        bis.close();
    }

    /**
     * 文本解码
     * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
     */
    public static String decodeText(String encodeText) throws UnsupportedEncodingException {
        if (encodeText == null || "".equals(encodeText)) {
            return "";
        } else {
            return MimeUtility.decodeText(encodeText);
        }
    }


实属无奈才使用这种方式,求一种更好的解决方法