【问题标题】:cannot append a message to a folder in javax.mail无法将消息附加到 javax.mail 中的文件夹
【发布时间】:2013-03-31 09:59:16
【问题描述】:

我正在设法保存包含正文、主题等的简单消息。但是,我无法保存多部分消息。我在appendMessages 之前和之后登录,但注意到第二个日志不存在。有趣的是,我根本没有任何例外被解雇。我完全不知道这里出了什么问题。

这是我的 Java 代码:

    Store store = null;
    Folder folder = null;
    String folderName = "sentbox";
    try {
        Session session = prepareSession(MailProtocols.IMAP, kid);
        store = session.getStore("imap");
        store.connect(myHost, user.getLogin(), user.getPassword());
        folder = store.getFolder(folderName);

        if (folder == null || !folder.exists()) {
            folder.create(Folder.HOLDS_MESSAGES);
        }
        folder.open(Folder.READ_WRITE);
        MimeMessage mimeMessage = new MimeMessage(session);
        Address[] to = null;
        if(msg.getTo() != null) { // msg is an instance of custom message class, nothing special there
            int msgSize = msg.getTo().size();
             to = new InternetAddress[msgSize];
            for (int i = 0; i < msgSize; i++) {
                to[i] = new InternetAddress(msg.getTo().get(i));
            }
        }

        mimeMessage.setRecipients(RecipientType.TO, to);
        mimeMessage.setSentDate(new Date(System.currentTimeMillis()));
        mimeMessage.setSubject(msg.getSubject());

        if (msg.getFiles() != null) {
            MimeMultipart mp = new MimeMultipart();
            MimeBodyPart newPart = new MimeBodyPart();
            newPart.setText(msg.getBody());
            mp.addBodyPart(newPart);
            for (MultipartFile multipartFile : msg.getFiles()) {
                try {
                    newPart = new MimeBodyPart(); // create new part to each files
                    newPart.addHeader("My-File-Type", multipartFile.getContentType());
                    File tmpFile = File.createTempFile("newAttachment", ".tmp");
                    multipartFile.transferTo(tmpFile);
                    FileDataSource fds = new FileDataSource(tmpFile);
                    newPart.setDataHandler(new DataHandler(fds));
                    newPart.setFileName(multipartFile.getOriginalFilename());
                    newPart.setDisposition(Part.ATTACHMENT);
                    mp.addBodyPart(newPart);
                    tmpFile.deleteOnExit();
                } catch (IOException e) {
                    logger.debug("Can not create temp file ===========>");
                    e.printStackTrace();
                }
            }
            mimeMessage.setContent(mp);
            mimeMessage.saveChanges();
        } else {
            mimeMessage.setText(msg.getBody());
        }

        folder.appendMessages(new Message[] {mimeMessage});

        Message[] allMessages = folder.getMessages();
        UIDFolder uidFolder = (UIDFolder) folder;
        long savedMsgId = uidFolder.getUID(allMessages[allMessages.length - 1]);
                    logger.info("savedMsgId",savedMsgId + "") //cannot get this output at all

    } catch (Exception e) {
        logger.error(e);

    } finally {
        closeMailStore(store, folder); // just simple method which closes the store
    }

我正在使用 Apache James 3.0.4。欢迎任何方法

【问题讨论】:

  • 可以在 appendMessages 方法里面调试吗?
  • 我会在可疑的代码区域中寻找 Throwable。如果你真的想得到更多的关注,你可以给我们更多的信息。你看起来好像在这里有一个完整的方法;提取整个方法,看看是否可以围绕它设置一个框架以在服务器外部运行。我不知道这是否可行,但如果可行,您可以了解很多关于它的知识,而无需通过所有服务器的东西。经常以这种方式发现错误,甚至在它们到达 SO 之前。

标签: java jakarta-mail james


【解决方案1】:

我使用的是 Apache James 3.0.4

你不是说 Apach James 3.0-beta4 吗?即我们还没有达到 3.0 版本,所以没有 3.0.4。您不使用稳定版本(2.3.2)的任何原因?只是问... :-)

我在 appendMessages 之前和之后进行了记录,但注意到第二个日志不存在。

如果您从未在 folder.appendMessages(new Message[] {m​​imeMessage}); 之后记录代码,那么有三种可能性:

  1. 在 javax.mail / IO 代码中抛出了一个错误(或 Throwable)。
    示例包括 IOError(讨厌的 IO 接口故障), LinkageError(不兼容的 jars/类)或 CoderMalfunctionError (如果解码/编码由 CharsetDecoder 或 CharsetEncoder 抛出 循环抛出意外异常)。
  2. 线程问题导致您的程序停止 - 即线程饥饿或死锁
  3. JVM 进程崩溃

第 (1) 项到目前为止在这里最有可能。 建议:将代码尾部改为:

} catch (Exception e) {
    logger.error(e);

} catch (Throwable t) {
    logger.error(t);

} finally {
    closeMailStore(store, folder); // just simple method which closes the store
}

如果这会记录一个 throwable,您可以根据应用 jar 和配置、OS/JVM 版本或数据内容来调查原因...

如果这没有记录可投掷,您可以调查 (2) 或 (3)。

【讨论】:

  • 感谢您的详细解释。我明天会检查并让你知道,上帝保佑。
  • 无法通过Throwable,并且2 没有成功(我确定没有死锁)。关于3,我的其他同事也遇到了同样的问题(所以可能没有任何JVM进程崩溃)。请看看我在@Marvik 的回答中的评论。我找到了另一种方法。谢谢!
【解决方案2】:

我在使用 James 2.3.2 时也遇到了同样的错误。我正在使用日食。在库设置中的 Eclipse 中,我添加了 JDK 来代替 JRE。然后我的问题就解决了。尝试相同。它可能会起作用,因为您的代码看起来不错,并且我认为的代码没有问题。

【讨论】:

  • 其实我已经试过了。但我一直无法解决这个问题。然后我决定改变程序,你知道,使用 Mailets。我正在使用org.apache.james.mailbox.MessageManager 类,它有一个名为append 的方法。那工作正常! :)
【解决方案3】:

我找到了另一种方法,我放在这里是希望我可以帮助其他人。 我正在覆盖 Mailet 的 service 方法。然后借助org.apache.james.mailbox.MessageManagerappendMessage 方法,我可以简单地将我的消息添加到我想要的文件夹中。这是我的 JAVA 代码:

public class MyMailet extends GenericMailet {


@Resource(name = "mailboxmanager")
private MailboxManager mailboxManager;

private String sentbox;

@Override
public void init() throws MessagingException {
    super.init();     

    this.sentbox = getInitParameter("sent", "sentbox");
}


@SuppressWarnings("unchecked")
@Override
public void service(Mail mail) throws MessagingException {
    // Here, I am putting my logic which has to decide which folder to put
    // ...


    putToFolder(mail.getMessage(), mail.getSender().toString(), sentbox);

    mail.setState(Mail.GHOST);
}   

private long putToFolder(MimeMessage message, String userName, String folderName) throws MessagingException {
    MailboxSession session = null;
    long appendedMessageId;
    try {
        session = mailboxManager.createSystemSession(userName, new MailetContextLog(getMailetContext()));

        MessageManager mailbox = getMessageManager(session, userName, folderName);
        appendedMessageId = mailbox.appendMessage(new MimeMessageInputStream(message), new Date(), session, true, null);

    } catch (BadCredentialsException e) {
        throw new MessagingException("Unable to authenticate to mailbox", e);
    } catch (MailboxException e) {
        throw new MessagingException("Unable to access mailbox.", e);
    } finally {
        if (session != null) {
            session.close();
        }

        try {
            mailboxManager.logout(session, true);
            mailboxManager.endProcessingRequest(session);
        } catch (MailboxException e) {
            throw new MessagingException("Can logout from mailbox", e);
        }

    }

    return appendedMessageId;
}

private MessageManager getMessageManager(MailboxSession session, String userName, String folderName) throws MailboxException, MessagingException {
    mailboxManager.startProcessingRequest(session);

    MailboxPath path = new MailboxPath(MailboxConstants.USER_NAMESPACE, userName, folderName);

    if (!mailboxManager.mailboxExists(path, session)) {
        mailboxManager.createMailbox(path, session);
    }
    MessageManager messageManager = mailboxManager.getMailbox(path, session);
    if (messageManager == null) {
        throw new MessagingException("Mailbox for username " + userName + " was not found on this server.");
    }

    return messageManager;
  } 
}

正如我所料,它会附加任何没有问题的多部分消息。

【讨论】:

    猜你喜欢
    • 2011-03-23
    • 2013-01-01
    • 2017-10-25
    • 2015-10-16
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    相关资源
    最近更新 更多