MimeBodyPart getContent会损坏二进制数据



我使用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. 输入的类型为byte Array,但在客户端上,getContent使用String进行响应。服务器将内容设置为应用程序/八位位组流,但在客户端,它被输出为字符串。这里出了什么问题
  2. 我不知道为什么在8c之前添加字节c2。8c角色有什么特别之处
  3. getInputStream和getRawInputStream之间有什么区别。什么时候使用一个而不是另一个

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

请注意,在不使用MimeMessage的情况下使用MimeMultipart,会丢失MimeMessage自动为您完成的一些事情,特别是丢失对MimeMultipart.updateHeaders()的调用。由于该方法是受保护的,因此在调用writeTo之前,您需要对MimeMultipart进行子类化并调用该方法。如果这还不能解决您的问题,请向我们展示流中正在写入和读取的确切数据。

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

如果getContent()返回一个String并且您想要二进制,请不要使用它。字符串不是二进制数据的容器。使用getInputStream()并复制字节。

最新更新