通过电子邮件发送大型附件

时间:2011-05-18 18:07:51

标签: java

是否有任何可用的包可以有效地发送带有大附件的电子邮件(每个文件的上限为10mb,但可能包含多个文件)。如果没有,关于适当设计的任何建议都不会导致内存异常导致在同一服务器上部署的应用程序之间出现问题?

文件通过ftp传递到应用程序服务器。传输完成后,将调用Web服务(事务的元数据)。根据业务规则,此服务可能需要通过电子邮件发送文件。

我最初的想法是将请求放在消息队列上(因此服务可以立即返回),并使用synchronized方法处理请求(因此多个请求在同一时间或大约同一时间不会炸毁堆) 。


使用代码

进行更新
messageBodyPart = new MimeBodyPart();
FileDataSource fileDataSource =new FileDataSource("locationTo.big.file");
messageBodyPart.setDataHandler(new DataHandler(fileDataSource));
messageBodyPart.setFileName("big.file");
multipart.addBodyPart(messageBodyPart);
<rinse..repeat>

message.setContent(multipart);

Transport.send(msg);

如果我附上5个10mb附件,50mb不会被堆一次吃掉?

2 个答案:

答案 0 :(得分:2)

为什么不使用Executor,线程池在合理范围内增长/缩小。提交的每个任务都是Runnable或Callable。 Task通过JavaMail发送,如果为附件和/或消息体实现自己的DataSource实现,则不会占用太多内存。 (我假设您已经让InputStream接受了附件)

添加代码作为样本(注意这段代码是多年前编写的,并且由于很多原因而非常糟糕。但它显示了这个概念)

public static void sendMailAndThrowException(SMTPParams sparams,String  subject, DataSource msgTextSource,DataSource[] fids,boolean debug) throws MessagingException {
    Session session=getMailSession(sparams);
PrintStream f = null;
if (debug) {            
        f= getPrintStream();        
} 
// null is System.out by javamail api
session.setDebug(debug);
session.setDebugOut(f);     

try
{
    // create a message
    MimeMessage msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress(sparams.getFrom()));

    // Recipients are comma delimitted
    String to_list[] = sparams.getRecipients().split(",");
    InternetAddress[] address = new InternetAddress[to_list.length];
    for( int i=0; i< to_list.length; i++)
    {
        // MJB: remove extraneous spaces, sanity check
        String temp = to_list[i].trim();
        if (temp.length()>0) {
            address[i] = new InternetAddress(to_list[i].trim());
        }
    }
    // Addresses are always TO, never CC  or BCC in this library
    msg.setRecipients(Message.RecipientType.TO, address);
        if ((msg.getAllRecipients() == null) || (msg.getAllRecipients().length==0)) {
            throw new MessagingException("No valid recipients");
        }

    // Set the subject
    msg.setSubject(subject,"UTF-8");

    // create the Multipart and add its parts to it
    Multipart mp = new MimeMultipart();


    if (msgTextSource != null) {
        // create and fill the first message part
        MimeBodyPart mbp1 = new MimeBodyPart();
        mbp1.setDataHandler(new DataHandler(msgTextSource));
        mp.addBodyPart(mbp1);
    }

    if( fids != null)
    {
        for (int i=0;i<fids.length;i++) {
            //  create the second message part
            if (fids[i]==null) continue;
            MimeBodyPart mbp2 = new MimeBodyPart();
            //  attach the file to the message
            mbp2.setDataHandler(new DataHandler(fids[i]));
            mbp2.setFileName(fids[i].getName());
            mp.addBodyPart(mbp2);
        }
    }

    // add the Multipart to the message
    msg.setContent(mp);

    // set the Date: header
    msg.setSentDate(new java.util.Date());

    // Connect to SMTP server
    smtpSend(session, msg, sparams);

}

catch (MessagingException mex)
{
    throw mex;
} finally {
    closeDebug(f);
}


}

答案 1 :(得分:0)

如果有足够的RAM来存放各种部分,JavaMail可以轻松发送带有大附件的邮件。

你不能使用它的任何特殊原因?