Java 未读邮件读取及解析

Posted OkidoGreen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 未读邮件读取及解析相关的知识,希望对你有一定的参考价值。

package com.dfham.cmdb.monitor.email;


import lombok.extern.slf4j.Slf4j;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import javax.mail.search.FlagTerm;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

@Slf4j
public class EmailAdapter 

    private static final String MAIL_IMAP_HOST = "imap.exmail.qq.com";
    private static final Properties props = new Properties();
    static 
        props.put("mail.imap.host", MAIL_IMAP_HOST);//QQ邮箱为:imap.qq.com
        props.put("mail.imap.auth", "true");
        props.setProperty("mail.store.protocol", "imap");
        props.put("mail.imap.starttls.enable", "true");
        props.setProperty("mail.imap.ssl.enable", "true");
        props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //端口
        props.setProperty("mail.imap.port","993");
    

    /**
     * 读取未读email邮件
     * @return
     */
    public static List<ImapEmailInfo> readEmails(String user,String password)
        List<ImapEmailInfo> result = new ArrayList<>();
        Session session = Session.getInstance(props);
        try 
            Store store = session.getStore();
            //企业邮箱如果开启了安全登录,密码需要使用专用密码,没有开启使用账号密码即可
            store.connect(MAIL_IMAP_HOST, user, password);
            Folder folder = store.getFolder("Inbox");
            //收取未读邮件,只读模式用于测试,READ_WRITE模式读取完成后邮件变成已读状态
            folder.open(Folder.READ_WRITE);
            //获得收件箱的邮件列表
            Message[] messages = folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN),false));
            log.info("[readEmails] 搜索结果-未读邮件数:" + messages.length);
            log.info("[readEmails] folder-未读邮件数:" + folder.getUnreadMessageCount());
            //解析的邮件的方法,就粘贴了网上的了,有需要的直接点击参考文档的链接
            parseEmail(result,messages);

            if (folder != null) folder.close(true);
            if (store != null) store.close();
        catch (Exception e)
            log.error("[readEmails] 异常: " + e.getMessage() ,e);
        
        return result;
    

    /**
     * 解析邮件并返回
     * @param result
     * @param messages
     */
    private static void parseEmail(List<ImapEmailInfo> result,Message[] messages) throws Exception 
        if (messages == null || messages.length == 0)
            log.info("没有可读取邮件");
            return;
        
        for(Message message : messages)
            MimeMessage msg = (MimeMessage) message;
            ImapEmailInfo emailInfo = new ImapEmailInfo();
            emailInfo.setSubject(MimeUtility.decodeText(msg.getSubject()));
            emailInfo.setSender(getSenderAddress(msg));
            StringBuffer content = new StringBuffer();
            String contentType = msg.getContentType();
            if (contentType.toLowerCase().startsWith("text/plain")) 
                gethtmlContent(msg, content, true);
             else 
                getHtmlContent(msg, content, false);
            
            emailInfo.setContent(content.toString());
            result.add(emailInfo);
        
    

    //获取邮件发件人address
    private static String getSenderAddress(MimeMessage msg) throws Exception 
        Address[] froms = msg.getFrom();
        if (froms.length < 1)
            throw new MessagingException("没有发件人!");
        InternetAddress address = (InternetAddress) froms[0];
        if(address != null)
            return address.getAddress();
        
        return null;
    


    //获取邮件内的HTML内容
    private static void getHtmlContent(Part part, StringBuffer content,boolean plainFlag) throws MessagingException, IOException 
        //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
        boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
        if (part.isMimeType("text/html") && !isContainTextAttach && plainFlag == false) 
            content.append(MimeUtility.decodeText(part.getContent().toString()));
         else if (part.isMimeType("text/plain") && !isContainTextAttach && plainFlag) 
            content.append(part.getContent().toString());
         else if (part.isMimeType("message/rfc822")) 
            getHtmlContent((Part) part.getContent(), content, plainFlag);
         else 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);
                getHtmlContent(bodyPart, content, plainFlag);
            
        
    

@Data
public class ImapEmailInfo implements Serializable 
    private static final long serialVersionUID = 6431149074654460271L;

    private String subject;
    private String sender;
    private String content;

以上是关于Java 未读邮件读取及解析的主要内容,如果未能解决你的问题,请参考以下文章

Gmail API 读取所有邮件而不是未读邮件

采用模拟账号读取Exchange server未读邮件的注意事项(链接邮箱问题)

从 Gmail 中检索未读电子邮件 - JavaMail API + IMAP

如何实现单击未读邮件后,该邮件仍显示为未读

有没哪个知道邮箱里的未读邮件查看以后,还可以让他显示为未读吗?

outlook 已读邮件怎么设置回未读,急!!