MimeBodyPart getContent破坏二进制数据 [英] MimeBodyPart getContent corrupts binary data

查看:107
本文介绍了MimeBodyPart getContent破坏二进制数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I use javax.mail.internet.MimeBody* version 1.4.1

我的程序想使用MimeMultiPart从服务器向客户端发送一些具有多层嵌套的二进制数据.我观察到,如果在某种程度上,如果我们使用GetContent,它将破坏数据.我可以用此代码段重现此问题

My program wants to send some binary data with multiple level of nesting from a server to client using MimeMultiPart. I observed that if on a level if we use GetContent it corrupts the data. I was able to reproduce this problem with this snippet

  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看起来很明显,但是我们有nestedMultiPart,顶层正在执行getContent,这在某些情况下会导致失败.

I have completely simplified the code here and it looks obvious to use get(Raw)InputStream, but we have nestedMultiPart and the top level was doing getContent which caused it to fail for some cases.

  1. 输入的类型为字节数组,但在客户端上,getContent使用String响应.服务器将内容设置为application/octet-stream,但在客户端将其作为字符串输出.这里出了什么问题?
  2. 我不确定为什么在8c之前添加字节c2. 8c角色有什么特别之处?
  3. getInputStream和getRawInputStream有什么区别.什么时候在另一个上使用?

推荐答案

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

What does the complete stream contain that the server is creating and the client is reading?

请注意,通过在不使用MimeMessage的情况下使用MimeMultipart,您会丢失MimeMessage为您自动完成的某些操作,尤其是您会丢失对MimeMultipart.updateHeaders()的调用.由于该方法是受保护的,因此您需要在调用writeTo之前子类化MimeMultipart并调用该方法.如果那不能解决您的问题,请向我们显示流中正在写入和读取的确切数据.

Note that by using MimeMultipart without MimeMessage, you're missing some of the things that are done automatically for you by MimeMessage, in particular you're missing the call to MimeMultipart.updateHeaders(). Since the method is protected, you'll need to subclass MimeMultipart and call that method before calling writeTo. If that doesn't fix your problem, show us the exact data that's being written and read on the stream.

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

As mentioned above, if you're expecting binary data, you almost certainly want to use getInputStream. The getRawInputStream gives you the data before it has been decoded, e.g., the base64 input instead of binary output.

这篇关于MimeBodyPart getContent破坏二进制数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆