我使用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看起来很明显,但是我们有nestedMultiPart,而顶层正在执行getContent,导致它在某些情况下失败。
答案 0 :(得分:1)
服务器正在创建并且客户端正在读取的完整流包含什么?
请注意,通过使用没有MimeMessage的MimeMultipart,您将错过MimeMessage为您自动完成的一些操作,特别是您错过了对MimeMultipart.updateHeaders()的调用。由于该方法受到保护,因此您需要继承MimeMultipart并在调用writeTo之前调用该方法。如果这不能解决您的问题,请向我们展示正在编写和在流上阅读的确切数据。
如上所述,如果你期待二进制数据,你几乎肯定想要使用getInputStream。 getRawInputStream在解码之前为您提供数据,例如base64输入而不是二进制输出。
答案 1 :(得分:0)
如果它返回一个String而你想要二进制文件,请不要使用getContent()。 String不是二进制数据的容器。使用getInputStream()并复制字节。