java - MimeBodyPart getContent 损坏二进制数据

标签 java mime jakarta-mail mime-mail

我使用 javax.mail.internet.MimeBody* 版本 1.4.1

我的程序想要使用 MimeMultiPart 将一些具有多层嵌套的二进制数据从服务器发送到客户端。我观察到,如果我们使用 GetContent,它会损坏数据。我能够用这个片段重现这个问题

  public static void CreateResponse() throws Exception {
        //Simulate the Server side
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        MimeMultipart multiPartValues = new MimeMultipart();
        MimeBodyPart valueBody = new MimeBodyPart();

        byte[] firstKeyValue = new byte[] { (byte)0x8c};
        valueBody.setContent(firstKeyValue,"application/octet-stream");
        valueBody.addHeader(RestMessageHeaders.CONTENT_LENGTH,
                Integer.toString(firstKeyValue.length));
        multiPartValues.addBodyPart(valueBody);

        Object input = valueBody.getContent();
        System.out.println(String.format("input %02X", ((byte[])input)[0]));
        multiPartValues.writeTo(outputStream);

        //Simulate the client side
        byte[] mimeOutput = outputStream.toByteArray();

        ByteArrayDataSource ds = new ByteArrayDataSource(mimeOutput,
                "multipart/mixed");
        MimeMultipart mp = new MimeMultipart(ds);
        MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(0);

        byte[] myOutput = new byte[1];
        //Verified that getContent returns a String, why ?? 
        Object output = part.getContent();
        System.out.println("getContent type " + output.getClass());
        String result = (String)output;
        ByteArrayDataSource partDS = new ByteArrayDataSource(result, "multipart/mixed");
        partDS.getInputStream().read(myOutput); 
        System.out.println(String.format("getContent %02X %02X", result.getBytes()[0],result.getBytes()[1]));
        System.out.println(String.format("getContent %02X", myOutput[0]));

        part.getInputStream().read(myOutput);
        System.out.println(String.format("getInputStream %02X", myOutput[0]));

        part.getRawInputStream().read(myOutput);
        System.out.println(String.format("getRawInputStream %02X", myOutput[0]));

}

这是输出

        input 8C
        getContent type class java.lang.String
        getContent C2 8C
        getContent C2
        getInputStream 8C
        getRawInputStream 8C

我已经完全简化了这里的代码,使用 get(Raw)InputStream 看起来很明显,但是我们有嵌套的MultiPart,并且顶层正在执行 getContent 这导致它在某些情况下失败。

  1. 输入是字节数组类型,但在客户端 getContent 以字符串响应。服务器将内容设置为 application/octet-stream 但在客户端以字符串形式输出。这里出了什么问题?
  2. 我不知道为什么在 8c 之前添加字节 c2。 8c 角色有什么特别之处?
  3. getInputStream 和 getRawInputStream 之间有什么区别。何时使用其中一种而不是另一种?

最佳答案

服务器正在创建且客户端正在读取的完整流包含什么?

请注意,如果使用不带 MimeMessage 的 MimeMultipart,您会错过 MimeMessage 自动完成的一些操作,特别是错过对 MimeMultipart.updateHeaders() 的调用。由于该方法是 protected ,因此您需要子类化 MimeMultipart 并在调用 writeTo 之前调用该方法。如果这不能解决您的问题,请向我们展示在流上写入和读取的确切数据。

如上所述,如果您需要二进制数据,那么几乎肯定要使用 getInputStream。 getRawInputStream 在解码之前为您提供数据,例如,base64 输入而不是二进制输出。

关于java - MimeBodyPart getContent 损坏二进制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23023583/

相关文章:

java - 使用 JavaMail 发送包含 Unicode 字符的邮件

java - 在没有主键的情况下在 hibernate 中插入演示数据

java - 将 JPanel 构造函数添加到 JPanel 显示灰色

java - Android Studio Spinner 导致应用程序在打开之前崩溃

java - 电子邮件 mime 解析

java - 想要在android中使用JavaMailAPI发送电子邮件。该代码工作正常并且所有信息都显示在日志中

java - 在java imap中获取X-Mailer

java - 使用现有 Hazelcast 实例初始化 SessionFactory

php - 安装自签名证书的弹出窗口

python - Django 管理员突然仅在生产环境中注销(拒绝执行脚本,因为其 MIME 类型 ('text/html' )不可执行)