在java中下载电子邮件附件

问题描述 投票:0回答:2

以下代码应该从邮件中下载任何附件(如果有)。 Gmali、pop3、javax.mail ...任何IDE如何执行此操作,也许针对邮件的特定发件人,或者检查该邮件是否在标题中存在特定单词或类似内容?

package emailattachmentsdownloader;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;
/**
 * This program demonstrates how to download e-mail messages and save
 * attachments into files on disk.
 *
 * 
 *
 */
public class EmailAttachmentsDownloader {
    private String saveDirectory;
    /**
     * Sets the directory where attached files will be stored.
     * @param dir absolute path of the directory
     */
    public void setSaveDirectory(String dir) {
        this.saveDirectory = dir;
    }
    /**
     * Downloads new messages and saves attachments to disk if any.
     * @param host
     * @param port
     * @param userName
     * @param password
     */
    public void downloadEmailAttachments(String host, String port,
            String userName, String password) {
        Properties properties = new Properties();

        // server setting
        properties.put("mail.pop3.host", host);
        properties.put("mail.pop3.port", port);

        // SSL setting
        properties.setProperty("mail.pop3.socketFactory.class",
                "javax.net.ssl.SSLSocketFactory");
        properties.setProperty("mail.pop3.socketFactory.fallback", "false");
        properties.setProperty("mail.pop3.socketFactory.port",
                String.valueOf(port));

        Session session = Session.getDefaultInstance(properties);

        try {
            // connects to the message store
            Store store = session.getStore("pop3");
            store.connect(userName, password);

            // opens the inbox folder
            Folder folderInbox = store.getFolder("INBOX");
            folderInbox.open(Folder.READ_ONLY);

            // fetches new messages from server
            Message[] arrayMessages = folderInbox.getMessages();

            for (int i = 0; i < arrayMessages.length; i++) {
                Message message = arrayMessages[i];
                Address[] fromAddress = message.getFrom();
                String from = fromAddress[0].toString();
                String subject = message.getSubject();
                String sentDate = message.getSentDate().toString();

                String contentType = message.getContentType();
                String messageContent = "";

                // store attachment file name, separated by comma
                String attachFiles = "";

                if (contentType.contains("multipart")) {
                    // content may contain attachments
                    Multipart multiPart = (Multipart) message.getContent();
                    int numberOfParts = multiPart.getCount();
                    for (int partCount = 0; partCount < numberOfParts; partCount++) {
                        MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
                        if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
                            // this part is attachment
                            String fileName = part.getFileName();
                            attachFiles += fileName + ", ";
                            part.saveFile(saveDirectory + File.separator + fileName);
                        } else {
                            // this part may be the message content
                            messageContent = part.getContent().toString();
                        }
                    }

                    if (attachFiles.length() > 1) {
                        attachFiles = attachFiles.substring(0, attachFiles.length() - 2);
                    }
                } else if (contentType.contains("text/plain")
                        || contentType.contains("text/html")) {
                    Object content = message.getContent();
                    if (content != null) {
                        messageContent = content.toString();
                    }
                }

                // print out details of each message
                System.out.println("Message #" + (i + 1) + ":");
                System.out.println("\t From: " + from);
                System.out.println("\t Subject: " + subject);
                System.out.println("\t Sent Date: " + sentDate);
                System.out.println("\t Message: " + messageContent);
                System.out.println("\t Attachments: " + attachFiles);
            }

            // disconnect
            folderInbox.close(false);
            store.close();
        } catch (NoSuchProviderException ex) {
            System.out.println("No provider for pop3.");
            ex.printStackTrace();
        } catch (MessagingException ex) {
            System.out.println("Could not connect to the message store");
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Runs this program with Gmail POP3 server
     */
    public static void main(String[] args) {
        String host = "pop.gmail.com";
        String port = "995";
        String userName = "MYMAIL";
        String password = "MYPASS";

        String saveDirectory = "D:/Attachments";

        EmailAttachmentsDownloader receiver = new 
        EmailAttachmentsDownloader();
        receiver.setSaveDirectory(saveDirectory);
        receiver.downloadEmailAttachments(host, port, userName, password);

    }
}

但是当我运行它时,出现以下错误。有什么问题,我该怎么办?

Exception in thread "main" java.lang.NoClassDefFoundError: 
com/sun/mail/util/MailLogger
at javax.mail.Session.initLogger(Session.java:227)
at javax.mail.Session.<init>(Session.java:212)
at javax.mail.Session.getDefaultInstance(Session.java:315)
at javax.mail.Session.getDefaultInstance(Session.java:355)
at emailattachmentsdownloader.EmailAttachmentsDownloader.downloadEmailAttachments(EmailAttachmentsDownloader.java:53)
at emailattachmentsdownloader.EmailAttachmentsDownloader.main(EmailAttachmentsDownloader.java:144)
Caused by: java.lang.ClassNotFoundException: com.sun.mail.util.MailLogger
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 6 more
C:\Users\Aca\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: 
Java returned: 1
BUILD FAILED (total time: 0 seconds)
java email jakarta-mail attachment
2个回答
0
投票

在 pom.xml 中添加以下依赖项并尝试再次重建:

<dependencies>
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.1</version>
    </dependency>
</dependencies>

0
投票

我在使用 Jakarta Mail API 时遇到问题。 附件的文件名 - 无论文件类型(.pdf、.tiff、.jpg) - 总是很奇怪,例如:

part.getFileName(): =?US-ASCII?B?Y3R5IFBhcmthdXN3ZWlzLnBkZg==?= part.getFileName() 与 MimeUtility: =?US-ASCII?B?Y3R5IFBhcmthdXN3ZWlzLnBkZg==?=

代码嵌入在下面。 我的系统:

IntelliJ IDEA 2022.2.4(终极版) 版本 #IU-222.4459.24,建于 2022 年 11 月 22 日 授权给公司/J.D. 您拥有此版本的永久后备许可证。 订阅有效期至 2024 年 12 月 31 日。 运行时版本:17.0.5+7-b469.71 amd64 VM:JetBrains s.r.o. 的 OpenJDK 64 位服务器 VM Windows 10 10.0 詹金斯插件 0.13.16-2022.2 GC:G1年轻代,G1老一代 内存:4096M 核心:16 注册表: debugger.watches.in.variables=false ide.tooltip.initialDelay=191

非捆绑插件: intellij 时钟 (2.0.0) com.mle.idea.sbtexecutor (1.4.1) com.markskelton.one-dark-theme (5.8.0) com.jetbrains.jax.ws (222.4459.16) com.genuitec.codetogether (2023.2.0-01430) 字符串操作 (9.6.1) 主要推动者 X (2022.2) Jira 浏览器 (0.3.3) Jenkins 控制插件 (0.13.16-2022.2) com.intellij.plugins.html.instantEditing (222.4459.16) com.atsebak.ui5 (2.05) Pythonid (222.4459.24) org.exbin.deltahex.intellij (0.2.7) MavenRunHelper (4.23.222.2964.0)

Kotlin:222-1.7.10-release-334-IJ4459.24

我的pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>de.ourcompany</groupId>
        <artifactId>pom.util</artifactId>
        <version>2.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>jakarta-mail</artifactId>
    <version>2.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>de.ourcompany</groupId>
            <artifactId>util.config</artifactId>
            <version>2.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>de.ourcompany</groupId>
            <artifactId>util.cdi-transactionhandling</artifactId>
            <version>2.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>de.cortility</groupId>
            <artifactId>util.web</artifactId>
            <version>2.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>jakarta.mail</groupId>
            <artifactId>jakarta.mail-api</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>imap</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.angus</groupId>
            <artifactId>angus-mail</artifactId>
            <version>2.0.2</version>
            <scope>runtime</scope>
        </dependency>

        <!-- expression language for dynamic bean validation -->
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>jakarta.el</artifactId>
        </dependency>
        <!-- hibernate bean validation cdi integration -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator-cdi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet-core</artifactId>
        </dependency>


        <!-- Dependencies for testing only -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>de.ourcompany</groupId>
            <artifactId>util.cdi-testing</artifactId>
            <version>2.0.1-SNAPSHOT</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>de.ourcompany</groupId>
            <artifactId>component.dataexchange.mail</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

public JakartaMailFetcher(final Config config, final String messageBoxSource) throws MessagingException, FileNotFoundException {
    this.mailFetcherConfigTypes = config.getValueListAsString(JakartaMailFetcherMainConfig.MAIL_FETCHER_CONFIGURATIONS).toString();
    this.host = config.getValueAsString(JakartaMailFetcherMainConfig.MAIL_FETCHER_HOST);  // our company's host
    this.port = config.getValueAsInteger(JakartaMailFetcherMainConfig.MAIL_FETCHER_PORT); // 143
    this.user = config.getValueAsString(JakartaMailFetcherMainConfig.MAIL_FETCHER_USER);
    if (config.getValueAsBoolean(JakartaMailFetcherMainConfig.MAIL_FETCHER_PASSWORD_AUTHENTICATION)) {   // MAIL_FETCHER_PASSWORD_AUTHENTICATION = true
        this.password = config.getValueAsString(JakartaMailFetcherMainConfig.MAIL_FETCHER_PASSWORD);
    } else {
        this.password = null;
    }
    System.out.printf("JakartaMailFetcher(final Config config) => config: %s\n", config);
    System.out.printf("configurations available: %s\nhost: %s\nport: %s\npassword: ***\n", this.mailFetcherConfigTypes, this.host, this.port);
    System.out.println("Now calling this.initMailFetcher(messageBoxSource) ...");
    this.initMailFetcher(messageBoxSource);
    this.fetchMails();
}

private void initMailFetcher(final String messageBoxSource) {
    this.messageBoxName = messageBoxSource;

    try {
        this.initResultFileTxt();
        this.systemProperties = this.getSystemProperties();
        System.out.println("\necho >> this.mailSession = this.getMailSessionObject(this.systemProperties);");
        this.mailSession = this.getMailSessionObject(this.systemProperties);
        this.store = this.connectMailStore(this.mailSession);

    } catch (Exception ex) {
        System.out.println("Oops, got exception! " + ex.getMessage());
        logger.error("Ooop an exception happened", ex);
        }
}

private Properties getSystemProperties() {
    // Get a Properties object
    final Properties systemProperties = System.getProperties();
    System.out.printf("%s   %s  %s   %s   %s", this.protocol, this.host, this.port, this.user, this.password);
    if (this.protocol != null) {
        systemProperties.put("mail.store.protocol", this.protocol);
    }
    systemProperties.put("mail." + this.protocol + ".host", this.host);   // this.protocol = "imap";
    systemProperties.put("mail." + this.protocol + ".port", this.port);
    systemProperties.put("mail.user", this.user);

    if (this.password != null) {
        systemProperties.put("mail.password", this.password);
    }
    return systemProperties;
}

private Session getMailSessionObject(final Properties systemProperties) throws Exception {
    System.out.println("Session getMailSessionObject(final Properties systemProperties)");
    // Get a Session object
    final Session mailSession = Session.getDefaultInstance(systemProperties, null);
    mailSession.setDebug(debug);
    return mailSession;
}

private Store connectMailStore(final Session mailSession) throws MessagingException {
    Store store = null;
    if (this.url != null) {
        final URLName urlName = new URLName(this.url);
        store = mailSession.getStore(urlName);
        if (this.showAlert) {
            store.addStoreListener(new StoreListener() {
            @Override
            public void notification(final StoreEvent storeEvent) {
                final String storeEventMessageString;
                if (storeEvent.getMessageType() == StoreEvent.ALERT) {
                    storeEventMessageString = "ALERT: ";
                } else {
                    storeEventMessageString = "NOTICE: ";
                }
                System.out.println(storeEventMessageString + storeEvent.getMessage());
            }
            });
        }
        store.connect();
    } else {
        System.out.println("echo >> this.url == null");
        if (this.protocol != null) {
            store = mailSession.getStore(this.protocol);
        } else {
            store = mailSession.getStore();
        }

        // Connect
        if (this.host != null
            || this.user != null
            || this.password != null) {
            store.connect(this.host, this.port, this.user, this.password);
        } else {
            store.connect();
        }
    }
        return store;
}

public void fetchMails() throws MessagingException {
    try {
        // Open the Folder
        final Folder folder = getMailFolder(this.store);
        this.openMailFolder(folder);
        this.fetchMailsAndSaveAttachments(folder);

        folder.close(false);
        this.store.close();
    } catch (final Exception e) {
        throw new OurCompanysException(e);
    }
}

private Folder getMailFolder(final Store store) throws Exception {
    Folder defaultFolder = store.getDefaultFolder();
    final Folder javaCiMailInbox = store.getFolder(JAVA_CI_INBOX);
    final Folder[] defaultFolderSubFolders = store.getDefaultFolder().list();
    for (Folder fd : defaultFolderSubFolders) {
        System.out.println(">> " + fd.getName());
    }

    System.out.printf("JAVA CI INBOX >> %s\t %d messages", store.getFolder(JAVA_CI_INBOX).getName(), store.getFolder(JAVA_CI_INBOX).getMessageCount());
    System.out.printf("\nCTY_VERARBEITET >> %s\t%s messages", store.getFolder(CTY_VERARBEITET).getName(), store.getFolder(CTY_VERARBEITET).getMessageCount());
    System.out.printf("\nCTY_FEHLER >> %s\t%s messages", store.getFolder(CTY_FEHLER).getName(), store.getFolder(CTY_FEHLER).getMessageCount());

    if (defaultFolder == null) {
        System.out.println("No default defaultFolder");
    }

    if (this.messageBoxName == null) {
        this.messageBoxName = "INBOX";
    }

    assert defaultFolder != null;
    defaultFolder = defaultFolder.getFolder(this.messageBoxName);

    if (defaultFolder == null) {
        System.out.println("Invalid defaultFolder");
    }
    return javaCiMailInbox; // defaultFolder;
}

private void openMailFolder(final Folder givenFolder) throws MessagingException {
        // try to open read/write and if that fails try read-only
    try {
        givenFolder.open(Folder.READ_WRITE);
        } catch (final MessagingException messagingException) {
        givenFolder.open(Folder.READ_ONLY);
        }
    final int totalMessages = givenFolder.getMessageCount();

    if (totalMessages == 0) {
        System.out.printf("Folder %s is an empty folder\n", givenFolder);
        givenFolder.close(false);
        givenFolder.close();

        }
}

private void fetchMailsAndSaveAttachments(final Folder folder) throws Exception {
    final Message[] folderMessages = folder.getMessages();
    for (int counter = 0; counter < folderMessages.length; counter++) {
        System.out.println("\nmessage " + counter + " content:\n" + folderMessages[counter].getContent().toString());
        this.saveMessageAsEMLFile(folderMessages[counter], "");             // SAVE-AS-EML-FILE |--- JDU ---|
        if (this.saveAttachments) {
            this.saveMailAttachment((MimeMessage)folderMessages[counter], Arrays.asList(MimeType.PDF, MimeType.GIF, MimeType.JPEG, MimeType.TIFF));
        }
    }
        this.myWriter.close();
}

private void saveMessageAsEMLFile(final Message msg, final String filename) throws MessagingException, IOException {
    System.out.println("\nSaving message as .eml file and saving its attachment if available...");
    try {
        OutputStream out = null;
        try {
            final SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
            final String messageDate = dateFormat.format(msg.getSentDate());
            System.out.println("mail sent date in milliseconds" + messageDate);
            final String messageSubject = msg.getSubject();
            final String messageSender = msg.getFrom()[0].toString();
            final String whereToSave = this.test_root_path + sanitizeFilename(messageDate + "-" + messageSender) + ".eml";
            out = new FileOutputStream(new File(whereToSave));
            msg.writeTo(out);
        } catch (final MessagingException messagingException) {
        throw new OurCompanysException("Error while trying to save message file.", messagingException);
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }
    } catch (final IOException ioException) {
        throw new OurCompanysException("Error while trying to save message file.", ioException);
    }
}

private void saveMailAttachment(final MimeMessage givenMessage, final List<MimeType> mimeTypes) throws MessagingException, IOException, Exception {
    System.out.println("Entry of saveMailAttachment");
    System.out.println( givenMessage.getSubject() + " has contentType() -> " + givenMessage.getContentType());


    if (givenMessage.getContentType().contains("multipart")) {
        final Multipart multiPart = (Multipart) givenMessage.getContent();
        final int numberOfBodyParts = multiPart.getCount();
        System.out.println(givenMessage.getSubject() + " has " + numberOfBodyParts + " BodyParts");

        for (int partCount = 0; partCount < numberOfBodyParts; partCount++) {
            final BodyPart givenBodyPart = multiPart.getBodyPart(partCount);
            final MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
            final Object attachmentContent = part.getContent();

            logger.trace("Found attachment: \"{}\"", part.getContentType());
            for (final MimeType mimeType : mimeTypes) {
                if (StringUtils.startsWithIgnoreCase(part.getContentType(), mimeType.getValue())) {
                    logger.debug("Found suitable attachment: " + mimeType);
                    logger.debug("content type: " + attachmentContent.getClass());
                    final Attachment attachment = new Attachment();
                    attachment.setFileName(part.getFileName());
                    System.out.println("part.getFileName(): " + part.getFileName());
                    System.out.println("part.getFileName() with MimeUtility: " + MimeUtility.encodeText(part.getFileName(), "UTF-8", "B"));
                }
            }
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.