2017-06-02 58 views
1

我想發送郵件作爲附件在另一封郵件使用javax api。截至目前,我先保存在磁盤上的郵件,然後使用下面的代碼將其連接到另一個電子郵件: -如何發送一封郵件作爲另一封郵件的附件在Java中,而不保存到磁盤

 MimeMessage generateMailMessage = new MimeMessage(getMailSession); 
     generateMailMessage.setFrom(new InternetAddress("[email protected]")); 
     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("[email protected]")); 


     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")), "[email protected]", 
       (String) properties.get("mail.password")); 



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

有什麼辦法,我可以做的同樣的事情,但不保存連接電子郵件。我已經搜索出來,但發現要附加的文件可以存儲在內存中,但無法將郵件保存在內存中。

請建議。

感謝

+1

你可以使用'java.io.File'來創建一個臨時文件(並在它自己之後清理),像這樣https://stackoverflow.com/a/7083754/16959 –

回答

0

你可以寫一個附加的電子郵件不進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庫不僅可以從文件讀取,也可以從輸入流讀取)。在這種情況下ByteArrayInputStream會有所幫助,就像如下圖所示:

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

UPDATE

哦,我知道了... setDataHandler()接受DataHandler。並且DataHandler接受DataSource

但讓我們看看DataSource's 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)); 
... 
+1

setDataHandler接受DataHandler而不是ByteArrayInputStream 。 – Manish

+0

@Manish,我已經更新了有關您評論的答案。希望這會有所幫助。 – flaz14

相關問題