从CipherInputStream创建FormDataBodyPart时文件大小为0的问题
解决FormData传递解密流后对方收到空文件的问题
可能原因及对应解决方案
1. 流的读取指针位置异常
调试时如果已经读取过解密流(比如打印内容、校验长度),流的指针会移动到末尾,后续封装时就会读取不到内容。
- 解决方案:
- 如果是
ByteArrayInputStream,调用reset()方法重置指针到起始位置; - 如果是
CipherInputStream,因为它不支持reset(),需要重新调用decryptStream()获取新的流实例,避免复用已被读取过的流。
- 如果是
2. 未正确设置FormDataBodyPart的元数据
FormData需要明确指定文件的名称和Content-Type,否则服务端可能无法正确解析流:
// 示例:正确构建FormDataBodyPart CipherInputStream decryptStream = decryptStream(); // 先将解密流转为ByteArrayInputStream并缓存内容(确保能重复读取) ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = decryptStream.read(buffer)) != -1) { baos.write(buffer, 0, bytesRead); } decryptStream.close(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray()); FormDataBodyPart filePart = new FormDataBodyPart( FormDataContentDisposition.name("image").filename("encrypted-image.jpg").build(), byteArrayInputStream, MediaType.APPLICATION_OCTET_STREAM_TYPE );
3. 未指定流的内容长度
服务端可能依赖Content-Length头来读取文件内容,如果流没有提供长度信息,会导致读取到空内容。
- 解决方案:
- 提前将解密流的内容读取到字节数组,通过字节数组构建
ByteArrayInputStream,同时在FormDataBodyPart中指定内容长度:
- 提前将解密流的内容读取到字节数组,通过字节数组构建
byte[] fileBytes = baos.toByteArray(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileBytes); FormDataBodyPart filePart = new FormDataBodyPart( FormDataContentDisposition.name("image").filename("encrypted-image.jpg").size(fileBytes.length).build(), byteArrayInputStream, MediaType.IMAGE_JPEG_TYPE // 根据实际图片类型设置 );
4. 流提前被关闭
确保在发送请求的整个过程中,解密流或缓存的字节流没有被提前关闭。比如,不要在构建FormDataBodyPart后立即关闭流,要等到请求发送完成后再执行关闭操作。
验证步骤
- 确认缓存后的字节数组长度大于0,证明解密后的内容有效;
- 发送请求前,重置
ByteArrayInputStream的指针到起始位置; - 检查服务端接收代码是否正确解析FormData,是否完整读取了流内容。
内容的提问来源于stack exchange,提问作者Fatima
相关产品推荐
相关产品推荐

