java 使用非socket方式获取接收邮件 POP3 通过时间过滤

之前介绍了邮件接收方式是socket方式的,总的来说还比较靠谱。

当前这种方式,我试过邮件比较少得情况下,还是可以正常接收的,如果邮件一多的时候,邮件进行过滤,那么就非常非常慢。。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.SentDateTerm;

import com.ccjr.commons.util.MyDateUtil;
import com.sun.mail.pop3.POP3Folder;
import com.sun.mail.pop3.POP3Store;
import com.sun.mail.util.MailSSLSocketFactory;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ReciveITest {
    // 邮件
    String uid = "用户名";
    String pid = "密码";
    // 邮箱服务器
    String emailhost = "pop.exmail.qq.com";
    
    public static void main(String[] args) throws Exception{
        ReciveITest reciveIPopTest = new ReciveITest();
//        reciveIPopTest.receiveMail();
        reciveIPopTest.receiveMailFilter();
    }
    
    /**接收pop邮件*/
    public void receiveMailFilter() throws Exception  {

        POP3Store store = null;
        try {
            Properties properties = new Properties();
            properties.setProperty("mail.popStore.protocol", "pop3"); // 使用pop3协议
            properties.setProperty("mail.pop3.port", "995"); // 端口
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            properties.put("mail.pop3.ssl.socketFactory", sf);
            properties.put("mail.pop3.ssl.enable", true);
            properties.setProperty("mail.pop3.host", "pop.qq.com");
            Session session = Session.getInstance(properties);
            store = (POP3Store) session.getStore("pop3");
            store.connect(emailhost, 995, uid, pid);
            POP3Folder pop3Folder = (POP3Folder) store.getFolder("INBOX");
            pop3Folder.open(Folder.READ_ONLY); // 打开收件箱
            
            // 创建ReceivedDateTerm对象,ComparisonTerm.GE(大于等于),指定时间后的邮件
            Date fileDate = MyDateUtil.dateStrToDate(MyDateUtil.DATE_TIME_FMT, "2023-03-19 14:00:00");
            log.info("时间:" + MyDateUtil.dateToDateStr(MyDateUtil.DATE_TIME_FMT, fileDate));
            SentDateTerm term = new SentDateTerm(ComparisonTerm.GE, fileDate);
            Message[] messages = pop3Folder.search(term);
            
            
//            FetchProfile fetchProfile = new FetchProfile();
//            fetchProfile.add(FetchProfile.Item.ENVELOPE);
//            FlagTerm flagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
//            Message[] messages = pop3Folder.search(flagTerm);
//            pop3Folder.fetch(messages, fetchProfile);
            log.error("收件箱的邮件数:" + messages.length);
//            Folder folder = pop3Folder.getStore().getDefaultFolder();
//            Folder[] folders = folder.list();
//            for (int i = 0; i < folders.length; i++) {
//                log.error("名称:" + folders[i].getName());
//            }
            // 展示邮件内容
            this.showMessage(pop3Folder, messages);

        } catch (Exception e) {
            log.error("异常:",e);
        } finally {
            if (store != null) {
                store.close();
            }
        }
    }
    
    /**展示邮件内容
     * @throws Exception */
    public void showMessage(POP3Folder pop3Folder, Message[] messages) throws Exception {
        for (int i = 0; i < messages.length; i++) {
            String infomsg = "" + (i + 1) + "";
            log.info("---------------"+infomsg+"----------------start-----------------");
            MimeMessage emailMessage = (MimeMessage) messages[i];
            try {
                String from = MimeUtility.decodeText(emailMessage.getFrom()[0].toString());
                InternetAddress ia = new InternetAddress(from);
                log.info("发件人:" + ia.getPersonal() + '(' + ia.getAddress() + ')');
            }catch(Exception e) {
                e.printStackTrace();
                log.info("异常" + e.getMessage());
            }
//            注意UID与MessageID并非一个东西,UID是邮箱用来标识你这个账户的每一封邮件的东西,而MessageID是发送邮件的时候生成的唯一ID
//            log.info("发件人:" +msg.getFrom());
            log.info("ID:" + pop3Folder.getUID(emailMessage));
            log.info("主题:" + emailMessage.getSubject());
            log.info("发送时间:" + MyDateUtil.dateToDateStr(MyDateUtil.DATE_TIME_FMT, emailMessage.getSentDate()));
            log.info("类型:" + emailMessage.getContentType());
//            log.info("内容:" + msg.getContent());
            boolean isContainerAttachment = isContainAttachment(emailMessage);
            log.info("是否包含附件:" + isContainerAttachment);
//            if (isContainerAttachment) {
//                 //设置需要保存的目录并保存附件
//                String path = "D:\\upload\\"+MyDateUtil.dateToDateStr(MyDateUtil.DATE_FMT, emailMessage.getSentDate());
//                this.saveAttachment(emailMessage, path); //保存附件
//            }
            // 邮件设为已读
//            msg.setFlag(Flags.Flag.SEEN, true);
            log.info("---------------"+infomsg+"----------------end-----------------");
        }
    }

    /**
     * 判断邮件中是否包含附件
     * 
     * @param
     * @return 邮件中存在附件返回true,不存在返回false
     * @throws MessagingException
     * @throws Exception
     */
    public static boolean isContainAttachment(Part part) throws Exception {
        boolean flag = false;
        if (part.isMimeType("multipart/*")) {
            MimeMultipart multipart = (MimeMultipart) 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))) {
                    flag = true;
                } else if (bodyPart.isMimeType("multipart/*")) {
                    flag = isContainAttachment(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 = isContainAttachment((Part) part.getContent());
        }
        return flag;
    }

    /**
     * 保存附件
     * 
     * @param part 邮件中多个组合体中的其中一个组合体
     * @param destDir 附件保存目录
     * @throws UnsupportedEncodingException
     * @throws MessagingException
     * @throws FileNotFoundException
     * @throws IOException
     */
    public 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);
        }
    }

    /**
     * 读取输入流中的数据保存至指定目录
     * 
     * @param is 输入流
     * @param fileName 文件名
     * @param destDir  文件存储目录
     * @throws Exception
     */
    private void saveFile(InputStream is, String destDir, String fileName) throws Exception {
        File file = new File(destDir+File.separator + fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        // 如果文件名称包含关键字则进行保存
        BufferedInputStream bis = new BufferedInputStream(is);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
        int len = -1;
        while ((len = bis.read()) != -1) {
            bos.write(len);
            bos.flush();
        }
        bos.close();
        bis.close();
    }

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

}

 

posted on 2023-04-05 23:22  陈惟鲜的博客  阅读(428)  评论(0编辑  收藏  举报

导航