如何在Java中的另一封邮件中发送邮件,而无需将其保存到磁盘上

  • 本文关键字:磁盘 保存 Java java email attachment
  • 更新时间 :
  • 英文 :


我试图使用Javax API在另一封邮件中发送邮件作为附件。截至目前,我首先将邮件保存在磁盘上,然后使用以下代码将其连接到另一封电子邮件: -

        MimeMessage generateMailMessage = new MimeMessage(getMailSession);
        generateMailMessage.setFrom(new InternetAddress("abc@a.com"));
        String mailSubject = properties.getProperty("mail.subject");
        generateMailMessage
                .setSubject(mailSubject);
        generateMailMessage.setContent(emailBody, "text/html");
        generateMailMessage.addRecipient(Message.RecipientType.TO,
                new InternetAddress(properties.getProperty("message.recipienttype.to")));
        generateMailMessage.addRecipient(Message.RecipientType.CC,
                new InternetAddress(recipientEmail));

        File  file = new File(properties.getProperty("mail.draft.folder")+"mail.eml");
        FileOutputStream fos = new FileOutputStream(chatFile);
        generateMailMessage.writeTo(fos);
        Session getMailSession1 = Session.getDefaultInstance(mailServerProperties, null);
        MimeMessage generateMailMessage1 = new MimeMessage(getMailSession1);
        generateMailMessage1
                .setSubject("Attachment");
        generateMailMessage1.addRecipient(Message.RecipientType.TO,
                new InternetAddress("manish@xyz.com"));

        Multipart multipart = new MimeMultipart();
        MimeBodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setDescription("hahdsa");
        DataSource source = new FileDataSource(file);
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName("mail.eml");
        multipart.addBodyPart(messageBodyPart);
        generateMailMessage1.setContent(multipart);

        transport = getMailSession1.getTransport("smtp");
        if(!transport.isConnected())
            transport.connect(properties.getProperty("mail.host"),
                Integer.parseInt((String) properties.get("mail.smtp.port")), "abc@xyz.com",
                (String) properties.get("mail.password"));

        transport.sendMessage(generateMailMessage1, generateMailMessage1.getAllRecipients());
        transport.close();

有什么办法可以在不保存附件的电子邮件的情况下做同一件事。我已经搜索了出来,但发现附加文件可以存储在内存中,但在内存中无处可保存邮件。

请建议。

谢谢

您可以将附件的电子邮件写入FileOutputStream而不是将其写入ByTearRayOutputStream中,因此电子邮件将留在RAM中。然后,您可以将流转换为字节数组并发送。像这样(这不是下面的纯Java代码,没有例外处理,关闭流等,这只是一个伪代码,可以说明这一想法(:

...
ByteArrayOutputStream emailOutputStream = new ByteArrayOutputStream();
generateMailMessage.writeTo(emailOutputStream);
...
MimeBodyPart messageBodyPart = new MimeBodyPart();
...
byte[] email = emailOutputSteam.toByteArray();
messageBodyPart.setDataHandler(email);
...

唯一的问题是如何将电子邮件数据附加到消息主体。我不熟悉您使用的电子邮件API。可能不是指定字节数组作为MimeBodyPart.setDataHandler()方法的参数。但是MimeBodyPart.setDataHandler()方法很可能可以接受蒸汽(顺便说一句,大多数Java库不仅可以从文件中读取,而且还可以从输入流中读取(。在这种情况下

...
ByteArrayOutputStream emailOutputStream = new ByteArrayOutputStream();
generateMailMessage.writeTo(emailOutputStream);
...
MimeBodyPart messageBodyPart = new MimeBodyPart();
...
ByteArrayInputStream emailInputStream = ByteArrayInputStream(emailOutputSteam.toByteArray());
messageBodyPart.setDataHandler(emailInputStream);
...

update

哦,我看到... setDataHandler()接受DataHandlerDataHandler接受DataSource

,但让我们看看DataSource的Javadoc。已经提供了两种实现:FileDataSourceURLDataSource。实现从字节数组中获取数据的新数据源并不难。只有很少的方法必须实现。同样,下面的代码被大大简化。但这带来了数据流是通用概念的想法。实现DataSource接口后,DataHandler类甚至不会注意到实际数据是针对RAM(或数据库或其他任何数据(:

public class ByteArrayInputStreamDataSource {
    private ByteArrayInputStream stream;
    public ByteArrayInputStreamDataSource(byte[] data) {
        this.stream = new ByteArrayInputStream(data);
    }
    public String getContentType() {
        return "Your content MIME type, perhaps, it will be text/html ...";
    }
    public InputStream getInputStream() {
        return stream;
    }       
    public String getName() {
        return "Some meaningful name";
    }
    public OutputStream getOutputStream() {
        throw new UnsupportedOperationException("Modification of the datasource is not allowed.");
    }
    public void close() {
        // This method is not required by DataSource interface. 
        // But once we deal with stream generally it will be better 
        // to put here logic that closes the stream gracefully.
        // As for ByteArrayInputStream there is no need to close it 
        // according to Javadoc:
        // https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html#close()
    }
}

因此我们的自定义数据源可以像这样使用:

...
ByteArrayOutputStream emailOutputStream = new ByteArrayOutputStream();
generateMailMessage.writeTo(emailOutputStream);
...
MimeBodyPart messageBodyPart = new MimeBodyPart();
...
DataSource byteArraySource = new ByteArrayInputStream(emailOutputStream.toByteArray());
messageBodyPart.setDataHandler(new DataHandler(byteArraySource));
...

最新更新