You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何用JavaMail读取Gmail正文、附件及转发邮件?

How to Read Full Gmail Content (Body, Attachments, Forwarded Messages) in Java

Hey there! I'll walk you through fixing your code and building a solution that can read all content from Gmail messages—including the main body, attachments, and even forwarded messages. Let's start with the basics, then dive into the improved code.

First: Pre-Requisites for Gmail Access

Before coding, make sure these are set up in your Google account:

  • Enable IMAP in Gmail: Go to Gmail Settings → Forwarding and POP/IMAP → Enable IMAP.
  • Use an App Password (if 2FA is enabled): If you have two-factor authentication turned on, you can't use your regular password. Generate an app password from your Google Account Security settings (look for "App passwords" under "Signing in to Google").

Issues in Your Current Code

Let's quickly spot the problems in your ReadMail.java:

  • You're incorrectly fetching inbox.getMessage(count) inside the loop instead of using the current message object.
  • You're not handling MIME multipart content—Gmail messages (especially those with attachments or forwards) are structured as nested MIME parts, not plain text.
  • Calling message.getContent() directly won't parse forwarded messages or extract attachments properly.

Complete Solution Code

Here's an improved version that handles all your requirements. I've added helper methods to recursively parse MIME parts, extract attachments, and capture forwarded content:

import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ReadMail {
    // Directory to save attachments (create this folder first!)
    private static final String ATTACHMENT_DIR = "./gmail_attachments/";

    public static void main(String[] args) throws MessagingException, IOException {
        // Set up TLS properties for secure connection
        System.setProperty("https.protocols", "TLSv1.2");
        Properties props = new Properties();
        props.put("mail.imap.ssl.enable", "true");
        props.put("mail.imap.auth", "true");

        // Create session with secure authentication
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // Replace with your Gmail username and app password
                return new PasswordAuthentication("your-gmail@example.com", "your-app-password");
            }
        });

        // Connect to Gmail IMAP server
        Store store = session.getStore("imaps");
        store.connect("imap.googlemail.com", 993);

        // Open inbox folder in read-write mode
        Folder inbox = store.getFolder("INBOX");
        inbox.open(Folder.READ_WRITE);

        System.out.println("Total messages in inbox: " + inbox.getMessageCount());

        // Search for SEEN messages (change to false to target UNSEEN)
        Message[] messages = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), true));

        for (Message message : messages) {
            System.out.println("\n=== Processing Message #" + message.getMessageNumber() + " ===");
            System.out.println("Subject: " + message.getSubject());
            System.out.println("From: " + message.getFrom()[0]);
            System.out.println("Sent Date: " + message.getSentDate());

            // Parse full content: body, attachments, forwarded messages
            parseMessageContent(message);
        }

        // Clean up resources
        inbox.close(false);
        store.close();
    }

    /**
     * Recursively parse MIME parts to extract all content types
     */
    private static void parseMessageContent(Part part) throws MessagingException, IOException {
        // Handle multi-part messages (most Gmail messages fall into this category)
        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);
                parseMessageContent(bodyPart); // Recurse to handle nested parts
            }
        } 
        // Handle forwarded messages (embedded as message/rfc822 type)
        else if (part.isMimeType("message/rfc822")) {
            System.out.println("\n--- Forwarded Message ---");
            Message forwardedMessage = (Message) part.getContent();
            System.out.println("Forwarded Subject: " + forwardedMessage.getSubject());
            System.out.println("Forwarded From: " + forwardedMessage.getFrom()[0]);
            // Parse the content of the forwarded message itself
            parseMessageContent(forwardedMessage);
        } 
        // Handle attachments
        else if (part.getFileName() != null && !part.getFileName().isEmpty()) {
            String fileName = part.getFileName();
            System.out.println("\nSaving Attachment: " + fileName);
            saveAttachment((MimeBodyPart) part, ATTACHMENT_DIR + fileName);
        } 
        // Handle plain text or HTML body content
        else if (part.isMimeType("text/plain") || part.isMimeType("text/html")) {
            String content = (String) part.getContent();
            System.out.println("\nMessage Body:");
            System.out.println(content);
        }
    }

    /**
     * Save attachment to local directory
     */
    private static void saveAttachment(MimeBodyPart bodyPart, String filePath) throws IOException, MessagingException {
        InputStream inputStream = bodyPart.getInputStream();
        FileOutputStream outputStream = new FileOutputStream(filePath);

        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        inputStream.close();
        outputStream.close();
    }
}

Key Features Explained

  • Recursive MIME Parsing: The parseMessageContent method digs into all nested parts of the message, so it catches forwarded messages (which are embedded as message/rfc822 parts) and multi-part body content.
  • Attachment Handling: Detects attachment parts and saves them to a local folder—just make sure the gmail_attachments directory exists before running the code.
  • Forwarded Message Support: Recognizes forwarded messages and parses their content just like regular messages, so you don't miss any nested content.
  • Secure Authentication: Uses an Authenticator class instead of hardcoding credentials directly, which is a safer practice.

Quick Adjustments You Can Make

  • To process unread messages instead of seen ones, change the FlagTerm to new FlagTerm(new Flags(Flags.Flag.SEEN), false).
  • If you only care about plain text body content, you can skip the HTML handling logic in the parseMessageContent method.
  • Modify the ATTACHMENT_DIR path to save files to a different location on your system.

内容的提问来源于stack exchange,提问作者qwerty asdfgh

火山引擎 最新活动