You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java在Gmail中按指定主题与日期查询并提取邮件内容

嘿,我来帮你搞定这个问题!不用遍历所有邮件的核心是利用JavaMail的服务器端搜索功能,让Gmail直接帮你筛选符合条件的邮件,效率比本地遍历高太多了。下面是完整的实现方案,一步步来:

核心思路

JavaMail提供了SearchTerm接口,可以组合多个查询条件(比如主题、日期),让邮件服务器直接返回匹配的结果,避免本地遍历全部邮件。我们需要构造两个条件:「当日日期」和「指定主题」,然后用逻辑与组合起来执行搜索。

完整代码实现
import java.io.IOException;
import java.util.Calendar;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.AndTerm;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.SubjectTerm;

public class GmailSearchExample {
    public static void main(String[] args) {
        // 配置Gmail IMAP属性
        Properties props = new Properties();
        props.put("mail.imap.host", "imap.gmail.com");
        props.put("mail.imap.port", "993");
        props.put("mail.imap.ssl.enable", "true");
        props.put("mail.imap.auth", "true");

        // 认证信息(注意:Gmail需要应用专用密码,前提是开启2步验证)
        Authenticator auth = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("your-email@gmail.com", "your-app-specific-password");
            }
        };

        Session session = Session.getInstance(props, auth);
        try (Store store = session.getStore("imap")) {
            store.connect();
            Folder inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_ONLY);

            // 1. 构造当日日期条件:从今天00:00到明天00:00
            Calendar todayStart = Calendar.getInstance();
            todayStart.set(Calendar.HOUR_OF_DAY, 0);
            todayStart.set(Calendar.MINUTE, 0);
            todayStart.set(Calendar.SECOND, 0);
            todayStart.set(Calendar.MILLISECOND, 0);

            Calendar tomorrowStart = Calendar.getInstance();
            tomorrowStart.add(Calendar.DAY_OF_MONTH, 1);
            tomorrowStart.set(Calendar.HOUR_OF_DAY, 0);
            tomorrowStart.set(Calendar.MINUTE, 0);
            tomorrowStart.set(Calendar.SECOND, 0);
            tomorrowStart.set(Calendar.MILLISECOND, 0);

            SearchTerm dateTerm = new AndTerm(
                new ReceivedDateTerm(ComparisonTerm.GE, todayStart.getTime()),
                new ReceivedDateTerm(ComparisonTerm.LT, tomorrowStart.getTime())
            );

            // 2. 构造主题条件:精确匹配目标主题(模糊匹配见下文说明)
            SearchTerm subjectTerm = new SubjectTerm("你的目标邮件主题");

            // 3. 组合两个条件:必须同时满足日期和主题
            SearchTerm combinedTerm = new AndTerm(dateTerm, subjectTerm);

            // 执行搜索,直接获取匹配的邮件
            Message[] matchedMessages = inbox.search(combinedTerm);

            // 处理匹配到的邮件,转换为字符串
            for (Message msg : matchedMessages) {
                String emailContent = extractEmailContent(msg);
                System.out.println("匹配到的邮件内容:\n" + emailContent);
            }

            inbox.close(false);
        } catch (MessagingException | IOException e) {
            e.printStackTrace();
        }
    }

    // 提取邮件内容为字符串的工具方法,支持纯文本和多部分邮件
    private static String extractEmailContent(Message msg) throws MessagingException, IOException {
        Object content = msg.getContent();
        if (content instanceof String) {
            return (String) content;
        } else if (content instanceof Multipart) {
            Multipart multipart = (Multipart) content;
            StringBuilder contentBuilder = new StringBuilder();
            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart part = multipart.getBodyPart(i);
                // 跳过附件,只提取正文
                if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
                    continue;
                }
                contentBuilder.append(extractEmailContent(part));
            }
            return contentBuilder.toString();
        } else if (content instanceof BodyPart) {
            return extractEmailContent((BodyPart) content);
        }
        return "";
    }
}
关键细节说明
  1. 日期条件调整:如果需要匹配「发送日期」而非「收件日期」,把ReceivedDateTerm换成SentDateTerm即可。
  2. 主题模糊匹配:如果不需要精确匹配主题,而是匹配包含某个关键词的主题,可以用StringTerm替代SubjectTerm:
    // 不区分大小写,匹配包含"目标关键词"的主题
    SearchTerm subjectTerm = new StringTerm(false, "目标关键词");
    
  3. Gmail认证注意事项:现在Gmail默认禁用了普通密码登录,你需要:
    • 开启Google账号的2步验证
    • 生成应用专用密码,替换代码中的密码字段

内容的提问来源于stack exchange,提问作者Mohit Tyagi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:53:29