我遇到了一个很奇怪的问题。基本上,我使用java邮件通过imap扫描邮箱,检查每封邮件,查找附件,然后阅读我感兴趣的附件。代码工作…除了在某些Windows7机器上,但它在大多数W7机器上工作。
奇怪的是例外情况(见下文)。

com.sun.mail.util.DecodingException: BASE64Decoder: Error in encoded stream: found valid base64 character after a padding character (=), the 10 most recent characters were: "am; name=9"
        at com.sun.mail.util.BASE64DecoderStream.decode(BASE64DecoderStream.java
:305)
        at com.sun.mail.util.BASE64DecoderStream.read(BASE64DecoderStream.java:1
44)
        at java.io.FilterInputStream.read(Unknown Source)

Base64解码流似乎正在尝试解码附件,但开始读取部分头的Base64块:异常中的“am;name=9”似乎是头中定义文件名(实际上以“9”开头)的部分。
从应用程序的日志复制:“found attachement 90txsj.zip”
我试着在邮件代码中找到一个钩子,让我的手接触到inputstream,以过滤掉头部的一些方法,但这似乎是不可能的。
那么,是否还有另一个不使用java邮件的imap客户机实现?或者有人知道如何在原始流和Base64解码器之间进行转换吗?

最佳答案

另一个你可能不知道的选择是Apache JAMES。james允许您实现自己的mailet,而不是轮询imap或pop3电子邮件帐户。Mailet是与http servlet等价的smtp。
大约十年前,我参与了一个项目,该项目需要集成到公司基础设施中,并自动将电子邮件内容发布到可搜索的数据库(opt-in,以便更容易遵守报告要求)。我们最初尝试沿着javamail路径前进,但很快就遇到了可伸缩性、安全约束和健壮性的问题。
安装apache james并不太困难,而且我们可以很容易地动态地将更新部署到mailet。在本例中,我们将传入的电子邮件重新打包到自己的pojo中,并通过java消息队列将其序列化。我们能够很好地分配队列中的实际处理负载。
mailet使用您定义的匹配器来确定是否要处理传入消息。匹配器使用提供的邮件对象进行决策。如果匹配者批准了消息,它将被发送到您的邮件集进行处理。
邮件对象包含对标准javax.mail.internet.MimeMessage的访问,标准getInputStream()对已解码的邮件具有getRawInputStream()权限,而则在邮件发送到服务器时获取该邮件。我们一直使用这些,因为我们必须提取附件,病毒扫描,然后上传到我们的搜索数据库与正确的消息。
我认为使用这种方法您会找到更多的自由,因为james是一个smtp服务器,您不必将邮件保存在需要定期清理的收件箱中。

10-05 22:11