使用现有的 InputStream 作为附件内容通过 javax.mail 发送电子邮件

2024-01-12

是否可以使用发送电子邮件javax.mail并使用“现有的”InputStream对于电子邮件附件内容?

目前我正在构建电子邮件消息,如下所示:

final MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Subject line");

final Multipart multipartContent = new MimeMultipart();

    final MimeBodyPart textPart = new MimeBodyPart();
    textPart.setText("Message body");
    multipartContent.addBodyPart(textPart);

    final MimeBodyPart attachmentPart = new MimeBodyPart();
    final DataSource source = new InputStreamDataSource("text/plain", "test.txt", new ByteArrayInputStream("CONTENT INPUT STREAM".getBytes()));
    attachmentPart.setDataHandler(new DataHandler(source));
    attachmentPart.setFileName("text.txt");
    multipartContent.addBodyPart(attachmentPart);

message.setContent(multipartContent);

InputStreamDataSource实现如下:

public class InputStreamDataSource implements DataSource
{
    private final String contentType;
    private final String name;
    private final InputStream inputStream;

    public InputStreamDataSource(String contentType, String name, InputStream inputStream)
    {
        this.contentType = contentType;
        this.name = name;
        this.inputStream = inputStream;
    }

    public String getContentType()
    {
        return contentType;
    }

    public String getName()
    {
        return name;
    }

    public InputStream getInputStream() throws IOException
    {
        System.out.println("CALLED TWICE: InputStreamDataSource.getInputStream()");
        return new BufferedInputStream(inputStream);
        //return new ByteArrayInputStream("THIS 'NEW' INPUT STREAM WORKS BUT 'EXISTING' INPUT STREAM RESULTS IN ZERO-BYTE ATTACHMENT".getBytes());
    }

    public OutputStream getOutputStream() throws IOException
    {
        throw new UnsupportedOperationException("Not implemented");
    }
}

The DataSource提供方法getInputStream()得到InputStream用于电子邮件附件内容。

如果我返回一个“新”InputStream这不依赖于“现有”InputStream然后就可以正常工作了。但是,如果我返回“现有”InputStream,则电子邮件消息将带有零字节附件。

是否可以使用发送电子邮件javax.mail,并使用“现有”InputStream对于电子邮件附件内容?


EDIT:

see https://community.oracle.com/thread/1590625 https://community.oracle.com/thread/1590625

TL;DR 使用ByteArrayDataSource


必须深入研究Oracle的源代码......https://java.net/projects/javamail/sources/mercurial/content/mail/src/main/java/javax/mail/internet/MimeBodyPart.java https://java.net/projects/javamail/sources/mercurial/content/mail/src/main/java/javax/mail/internet/MimeBodyPart.java

当前的 java 邮件实现在输入流上执行 2 次:

  1. 首先确定是否应将标头“Content-Transfer-Encoding”设置为 7 位或 8 位(请参阅内容传输编码 7 位或 8 位 https://stackoverflow.com/questions/25710599/content-transfer-encoding-7bit-or-8-bit)
  2. 然后当它真正写入消息时第二次

...这很糟糕,因为whole流(在慢速连接上可能有数百 MB)将被读取两次......并且对于一旦读取就被“消耗”的流正是导致这个问题。


我尝试的第一个“解决方法”是自己指定标头:

attachmentPart.setDataHandler(new DataHandler(source));
attachmentPart.setHeader("Content-Transfer-Encoding", "8bit");
attachmentPart.setHeader("Content-Type", ds.getContentType() + "; " + ds.getName());

...按照这个顺序,而不是相反...因为出于某种原因setDataHandler内部调用另一个方法invalidateContentHeaders这清除了"Content-Transfer-Encoding"再次标题(wtf?!)

Sounded great, the mail was sent, hooray!!! :D ... :( see next


附件已发送...但已损坏

我的邮件服务器中收到的文件已损坏。呵呵。Why?!。经过长时间的搜索并再次深入研究这个蹩脚的java邮件代码,我找到了它,他们通过管道传输了InputStream into a LineOutputStream这会改变你的行结尾binary数据。嗯。 java的邮件实现真是一团糟。 :/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用现有的 InputStream 作为附件内容通过 javax.mail 发送电子邮件 的相关文章

  • 如何查看Pocketsphinx词典中是否存在该单词?

    我只是想看看字典文件中是否存在字符串 字典文件位于问题底部 我想检查语音识别器是否可以识别单词 例如 识别器将无法识别字符串ahdfojakdlfafiop 因为字典中没有定义 所以 我可以检查某个单词是否在 pocktsphinx 词典中
  • HTTP 状态 404 - 请求的资源不可用

    在使用 MyEclipse IDE 中的 Tomcat 服务器和 Struts 2 框架时 我遇到了反复出现的问题 我将我的程序作为服务器应用程序运行 当它运行时 默认的index jsp 文件将成功打开 但应用程序的其他过去都不起作用 当
  • 是否可以在 Spring Batch 中结合分区和并行步骤?

    我只是想知道它在 Spring Batch 中可行吗 Step1Step2 流程 gt 流程1 流程2 流程3 Step3 其中每个flow1 gt 划分为 5 个 GridSizeflow2 gt 划分为 5 个 GridSizeflow
  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 如何打印整个字符串池?

    我想打印包含文字的整个字符串池String使用添加的对象intern 就在垃圾收集之前 JDK有没有隐式的方法来进行这样的操作 我们如何检查字符串池 EDIT The comment suggests that there may be a
  • 将链接对象转换为流或集合

    我想迭代堆栈跟踪 堆栈跟踪由可抛出对象组成 其 getCause 返回下一个可抛出对象 最后一次调用 getCause 返回 null 示例 a gt b gt null 我尝试使用 Stream iterable 这会导致 NullPoi
  • 由于连接超时,无法通过 ImageIO.read(url) 获取图像

    下面的代码似乎总是失败 URL url new URL http userserve ak last fm serve 126 8636005 jpg Image img ImageIO read url System out printl
  • Java 泛型/类型调度问题

    考虑以下程序 import java util List import java util ArrayList public class TypeTest public static class TypeTestA extends Type
  • 方法断点可能会大大减慢调试速度

    每当向方法声明行添加断点 在 Intellij IDEA 或 Android Studio 中 时 都会出现一个弹出窗口 方法断点可能会大大减慢调试速度 为什么会这样戏剧性地减慢调试速度 是我的问题吗 将断点放在函数的第一行有什么不同 Th
  • Java:从元素创建 DOM 元素,而不是文档

    如您所知 在 Java 中创建 Dom 元素的正确方法是执行以下操作 import org w3c dom Document import org w3c dom Element Document d Element e e d creat
  • 如何将 Spotlight for Help 插入本地化的 macOS 应用程序?

    我正在 macOS 上使用 Swing GUI 框架实现 Java 应用程序 当使用system外观和感觉以及screen菜单栏 Swing 自动插入一个搜索栏 called 聚光灯寻求帮助 https developer apple co
  • 如何将 XMP XML 块序列化为现有的 JPEG 图像?

    我有许多 JPEG 图像 其中包含损坏的 XMP XML 块 我可以轻松修复这些块 但我不确定如何将 固定 数据写回图像文件 我目前正在使用 JAVA 但我愿意接受任何能让这项任务变得容易的事情 这是目标关于 XMP XML 的另一个问题
  • @EnableTransactionManagement 的范围是什么?

    我试图了解正确的放置位置 EnableTransactionManagement多个 JavaConfig 上下文的情况下的注释 考虑以下场景 我在 JPAConfig java 和 AppConfig java 中有 JPA 配置以及一组
  • Install4j:如何在安装结束时执行命令行 java -jar filename.jar

    在 Intall4j 中 在安装结束时 我只想通过执行如下命令行来初始化某些内容 java jar filename jar 我怎样才能归档这个任务install4j Thanks 将 运行可执行文件或批处理文件 操作添加到 安装屏幕 并设
  • 参数动态时如何构建 JPQL 查询?

    我想知道是否有一个好的解决方案来构建基于过滤器的 JPQL 查询 我的查询太 富有表现力 我无法使用 Criteria 就像是 query Select from Ent if parameter null query WHERE fiel
  • 如何在java中使jpeg无损?

    有没有人可以告诉我如何使用编写 jpeg 文件losslessjava中的压缩 我使用下面的代码读取字节来编辑字节 WritableRaster raster image getRaster DataBufferByte buffer Da
  • 如何为 Jackson 编写一个包罗万象的(反)序列化器

    当您提前知道类型时 编写自定义序列化器非常容易 例如 MyType一个人可以写一个MyTypeSerializer extends StdSerializer
  • ExceptionHandler 不适用于 Throwable

    我们的应用程序是基于 Spring MVC 的 REST 应用程序 我正在尝试使用 ExceptionHandler 注释来处理所有错误和异常 I have ExceptionHandler Throwable class public R
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一
  • 阻止 OSX 变音符号为所有用户禁用 Java 中的 KeyBindings?

    注 我知道这个问题 https stackoverflow com questions 40335285 java keybinds stop working after holding down a key用户必须输入终端命令才能解决此问

随机推荐

  • 左右滑动可更改活动

    所以我有一个活动 其中有一个导航抽屉 我停用了滑动以打开该导航抽屉 仅当我单击该菜单的按钮时它才会打开 现在我想通过滑动来更改活动 就像在 iPhone 中一样 我已经这样做了 但我不确定这是正确的方法 这是我的代码 GestureDete
  • Installshield - 使用 powershell 检查注册表中的密钥失败

    我有一个带有 powershell CA 的 Installshield 项目 它检查某个注册表项是否存在并根据结果设置属性 手动执行脚本时注册表检查成功但失败 返回false当从Installshield执行时 CA 在 UI 序列期间执
  • 将.apk文件发送给客户审核

    我开发了一个 Android 应用程序 并在模拟器和设备上对其进行了测试 我想将 apk文件导出到客户端进行审核 我使用应用程序清单文件导出未签名的 apk 并将其发送 但它没有安装在他的手机上 我在这里阅读了多个问题 但没有得到任何具体信
  • jwt.verify() 的 Node.js 回调

    我的 Node js 服务器上有一个身份验证路由 用于对请求进行身份验证 app get loggedin auth function req res console log req authenticated res send req a
  • SQLite eventim 的时间输入和时间退出

    我有两张桌子 DATA and EVENTS 具有以下数据 EVENTS EventIndex ObjID LocID EventData EventTime EventType 83707365 3519434 10376 0 2013
  • pandas to_numeric downcast='signed' 返回 float64

    我有一个数据集 其中 pandas read csv 处理适当地将一些连续数字列 特征 变量数据从对象转换为 float64 int64 或 uint8 但不是其他数据 因此 然后我尝试使用以下指定向下转换参数的 pandas to num
  • 如何使用 Javascript 停止 YouTube 中的视频?

    情况 here http yvoschaap com videowall q sunset 20beautiful我在那里按了一些视频 Problem 我尝试在 Firebug 控制台中通过 Javascript 停止视频 player s
  • 从另一个表和不同的数据库更新表

    基本上 我想做的是 我的第一个数据库 prc 中有一个表 users 如下所示 prc user id user 45 name user Test login user test pwd user test 在我的第二个数据库 名为 pr
  • 使用 awk 替换 CSV 文件中的列值

    我有这个文件 错误日志 00 00 00 284 501 00 00 00 417 5 5294100071980 00 00 02 463 501 00 00 05 169 501 00 00 05 529 501 00 00 05 73
  • Delphi - 通用 TList 排序

    我正在使用 Generics Collections TList 和 Sort 方法 它工作正常 但我想最后对空值或空值进行排序 按升序和降序排序 如何实施 这是我的排序功能 function TForm SortByColumn Colu
  • 按行项目条件更改 MudBlazor 表背景颜色

    我正在尝试更改 mudblazor 表中一行的颜色 问题是 我无法添加根据行元素的条件更改颜色的功能
  • WPF 中的 PagedCollectionView 等效项?

    net 3 5 或 4 0 中是否有像 Silverlight 中的 PagedCollectionView 这样的 WPF 等效类 不 没有 但你可以从这里获取 https silverlight svn codeplex com svn
  • 确定可能的项目组的算法

    我正在摸不着头脑试图做到这一点 这让我筋疲力尽 我知道事情没那么复杂 我有很多物品 这个数量可以等于或大于三 然后我需要确定完成总数的项目组的可能组合 唯一的限制是小组应该有三个或更多项目 不超过 但包括 七个项目 例如 如果我有 7 个项
  • 为单词的前 n 个字符添加下划线

    我想在链接中的单词的前几个字符下划线 类似于 CSS 第一个字母的工作方式 但字母数量可变 或者 在单词字母的前半部分下划线可能会很有用 有什么方法可以使用 HTML CSS 或 Javascript 相对简单地完成此操作吗 我不是开发人员
  • Uncrustify 折叠 多行函数调用

    我的函数调用如下所示 没有明显的原因 func a b c 有没有办法让 uncrustify 将函数折叠成一行 我已经尝试了两天了 没有断断续续的 我让它适用于函数声明 但我没有让它适用于函数调用 当我们这样做时 我也有如下所示的函数 f
  • 为什么是语句(j++);禁止?

    下面的代码是错误的 看一下关于ideone http ideone com vSoRsM public class Test public static void Main int j 5 j if we remove the and th
  • 地点选择器启动后关闭

    我无法从我的片段启动 Google 地点选择器 按照所有步骤和论坛查找根本原因 但无法解决我的问题 Links 谷歌地点选择器 https developers google com places android api placepick
  • 领域:谓词返回 LazyFilterCollection - 如何转换为 Results

    我正在过滤我的数据库查询NSPredicate直接在数据库上 但我想进一步过滤返回的值 Results
  • 在react-navigation createStackNavigator中使用mobx存储

    我想在react navigation中的createStackNavigator中使用Mobx存储变量 具体来说 我想使用商店动态更改初始路线 以便用户可以更改初始屏幕 这可能吗 一些东西在 const stack createStack
  • 使用现有的 InputStream 作为附件内容通过 javax.mail 发送电子邮件

    是否可以使用发送电子邮件javax mail并使用 现有的 InputStream对于电子邮件附件内容 目前我正在构建电子邮件消息 如下所示 final MimeMessage message new MimeMessage session