JavaMail InputStream附件需要永远

时间:2014-02-02 22:16:07

标签: java javamail inputstream attachment

我正在尝试发送附件的电子邮件。附件是即时生成的,因此没有文件,我无法在文件系统上创建临时文件。

InputStream attachment

我试图直接使用JavaMail和apache.commons.mail。两者都有相同的结果。浏览器保持“等待localhost”需要6分钟。我怀疑问题是邮件库并不真正知道InputStream有多大(或者他们没有正确处理InputStream)所以他们等到一些超时然后发送邮件。我已经使用文件(通过FileDataSource和其他)进行了测试,它工作正常,但没有使用InputStream ......

有没有办法让它在没有让用户永远等待的情况下工作?当然减少timeOut不是一个好的解决方案,因为我不知道连接的速度有多快另一方面,我不想让快速用户等待发送200KB的电子邮件。

 // Create the email message
    MultiPartEmail email2 = new MultiPartEmail();
    email2.setHostName(host);
    email2.setAuthenticator(new DefaultAuthenticator(username, password));
    email2.setSSLOnConnect(true);
    email2.setFrom(username);
    email2.setSmtpPort( Integer.parseInt(port) );
    email2.addTo(to);
    email2.setSubject("MAIL");
    email2.setMsg("Text");

    DataSource source = new ByteArrayDataSource(attachment, "application/pdf");  
    // add the attachment
    email2.attach(source, "somefile.pdf", "Description of some file");
    email2.send();

此代码将正确发送邮件...但是在6分钟或更长时间之后。

修改

我在代码中放了一些痕迹:

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println("Start: " + dateFormat.format(date));
 // Create the email message
    MultiPartEmail email2 = new MultiPartEmail();
    email2.setHostName(host);
    email2.setAuthenticator(new DefaultAuthenticator(username, password));
    email2.setSSLOnConnect(true);
    email2.setFrom(username);
    email2.setSmtpPort( Integer.parseInt(port) );
    email2.addTo(emailTO);
    email2.setSubject("MAIL");
    email2.setMsg("Text");
date = new Date();
System.out.println("Before DataSource: " + dateFormat.format(date));
    DataSource source = new ByteArrayDataSource(attachment, "application/pdf");  
date = new Date();
System.out.println("After DataSource: " + dateFormat.format(date));
    // add the attachment
    email2.attach(source, "somefile.pdf", "Description of some file");
date = new Date();
System.out.println("Before send(): " + dateFormat.format(date));
    email2.send();
date = new Date();
System.out.println("After send(): " + dateFormat.format(date));

结果如下:

Start: 2014/02/24 16:18:01
Before DataSource: 2014/02/24 16:18:01
After DataSource: 2014/02/24 16:18:01
Before send(): 2014/02/24 16:18:01
Feb 24, 2014 4:18:01 PM org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage getColorSpace
INFO: About to return NULL from unhandled branch. filter = COSName{DCTDecode}
After send(): 2014/02/24 16:26:35

如果我对email2.attach(...)发表评论我得到了这个:

Start: 2014/02/24 16:28:56
Before DataSource: 2014/02/24 16:28:56
After DataSource: 2014/02/24 16:28:56
Before send(): 2014/02/24 16:28:56
After send(): 2014/02/24 16:29:27

当然需要很长时间,但这是可以接受的......

现在,很明显问题与附件有关。我不知道我收到的PDFBox警告是什么,但是......

编辑2

我现在正在测试没有附件,发送电子邮件只需要5秒钟......所以它看起来与看到InputStream的方式有关。

编辑3

我启用了调试,似乎在附件中消耗了时间。我看到send()做什么和打印:

------=_Part_0_2141791733.1395266799862
Content-Type: application/pdf; name="my.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="my.pdf"
Content-Description: 

JVBERi0xLjQKJfbk/N8KMSAwIG9iago8PAovTWFya0luZm8gMiAwIFIKL01ldGFkYXRhIDMgMCBS

...然后send()以这样的方式一点一点地打印附件内容:

MhKxjVRnwA6I8BisAX1VTXc0hw1DXO0lBcQJDQpWFZPU3oX2YogU3Y0SbgFxKBCJWzUEqfJIQ5Bh
GrYDx1o3JOIYHZPnVRZHa4EA0FqGxiZk6MdkEfYakPO4MW1jXIjeKFMxdL1XY84nrGDMwoyCkC3N
TJOAJITplbIewNEXv6u8AIf64hiZIm+x4jyFOxzk5DzfSONJiDiKbtozF+Yz+g90lJOCLiRFneuV
3AYDQAD1gnW+odwoSVBAUezLL5Zwue1yttDySw5zVsaE9j7kv9mHpOlnTephlZR5fiu/f+XEOb/O
qQ6suP2zOl/3KRw+OMiXC5hNGlAca7d2XWDMLIiQs45yUsCnljRLVdYFKz7Zg6zcsiH9kaupwOe4
ifPEiXe/8LEok2So8o3Bp5XysDadYxsllfVLlNdLXlQc+2R+kdFHam5ydBm5HkYl5ZCwF2vPKpvU

然后需要几秒钟......并打印另一个块。此过程持续约6分钟。直到完成:

MjRDODdCODVGMEEyQjBBMzVDQj4gPEM5MjBBRjU5Q0MxOEM2NDI5MDM4REIzMEI2OUE0REQ5Pl0K
L1Jvb3QgMSAwIFIKL0luZm8gNyAwIFIKL1hSZWZTdG0gMTYxOAo+PgpzdGFydHhyZWYKNDEzNjI5
CiUlRU9GCg==
------=_Part_0_690515382.1395264718480--
.
250 OK id=4WQO3h-0004D1-VQ
QUIT
221 mail2.... closing connection

我猜InputStream有问题。没有附件或从文件中获取附件,它可以正常工作。附件只有~0.4MB

也许有InputStream的创建方式。然而,它似乎很奇怪,因为我使用完全相同的方法下载PDF,下载工作正常。

    ByteArrayOutputStream os = new ByteArrayOutputStream();
    pd.save(os);
    return new ByteArrayInputStream( os.toByteArray() );

1 个答案:

答案 0 :(得分:1)

究竟哪个陈述一直在进行?它是否正在创建ByteArrayDataSource?或者是发送方法? ByteArrayDataSource立即将所有数据复制到字节数组中。如果那就是所有的时间,你可以自己更有效地做到这一点。但如果所有时间都在send方法中,则可能是您的邮件服务器速度很慢。