【问题标题】:MultipartEntity: Content-Length for InputStreamMultipartEntity:InputStream 的内容长度
【发布时间】:2016-01-05 01:49:23
【问题描述】:

我正在尝试从 multipart/form-data 中的输入流发送数据,作为文件参数使用:

MultipartEntityBuilder.create()
            .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
            .addBinaryBody("file", inputStream)
            .build();

问题是服务器似乎需要一个 Content-Length 标头。我知道 inputStream 的正确大小 - 我可以手动设置吗?

【问题讨论】:

  • InputStream 可以放入内存吗?你是这样知道它的大小的吗?
  • 不,InputStream 是一个提供内容长度的 http 响应。但我想“重定向”它(它已经有效,但没有提供内容长度)。

标签: java apache-httpcomponents


【解决方案1】:

您可以使用ContentBody 创建自己的FormBodyPart,而不是使用addBinaryBody 方法。适当的ContentBodyInputStreamBody,但它的getContentLength 方法返回-1

我建议您扩展该类以提供自定义内容长度。

class KnownSizeInputStreamBody extends InputStreamBody {   
    private final long contentLength;

    public KnownSizeInputStreamBody(InputStream in, long contentLength, ContentType contentType) {
        super(in, contentType);
        this.contentLength = contentLength;
    }

    @Override
    public long getContentLength() {
        return contentLength;
    }
}

然后您可以将您的多部分实体创建为

FormBodyPart bodyPart = FormBodyPartBuilder.create().setName("file")
        .setBody(new KnownSizeInputStreamBody(inputStream, contentLenth, ContentType.APPLICATION_OCTET_STREAM)).build();

HttpEntity entity = MultipartEntityBuilder.create().addPart(bodyPart).build();

视情况而定(您自己的内容类型、内容长度、名称等)。

在我的例子中,http 客户端为整个多部分请求正文编写了内容长度,而不是每个部分。

【讨论】:

  • 效果很好,谢谢。对于文件名参数,我必须将.setField("Content-Disposition", "form-data; name=\"file\"; filename=\"" + filename + "\"") 添加到FormBodyPartBuilder
  • @G.Rossi 啊不,不要那样做。我认为InputStreamBody 有一个接受文件名的构造函数。使用那个。
  • 哦,我想,我错过了那个。但是,是的,你是对的——这样更好。
  • 如果你想为一个部件设置一个Content-Length标题,你可以做FormBodyPartBuilder.create().addField("Content-Length", "42")...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
相关资源
最近更新 更多