繁体   English   中英

我可以跳过实现HttpEntity#getContent()吗?

[英]Can I skip implementing HttpEntity#getContent()?

我打算将结构化数据写入通过HTTP客户端访问的资源。 用于执行此操作的API(针对JSON,YAML,XML)通常使我将它们传递给他们的OutputStream传递给它们-它们没有给我InputStream

不管是好是坏,Apache HTTP Components HttpClient是此处使用的客户端。 (我们使用的其他库依赖于它。在大多数情况下,这并不完全不好,至少不强迫我们使用怪异的线程本地hack来获得理智的行为,这与java.net.URL不同。)

发出请求时, HttpEntityEnclosingRequestBase (在HttpClient中)迫使我设置HttpEntity以将任何数据发送到服务器。 HttpEntity似乎迫使我实现getContent() ,并返回InputStream

我没有InputStream ,所以我不得不在两种解决方法之间进行选择:

A)将所有数据序列化为内存中的字节数组,然后再次将其全部流回。 我不想这样做,因为通常情况下,数据的序列化形式要比数据本身占用更多的内存,并且在某些情况下,我们甚至根本不将其存储在内存中,因此这会自找麻烦。

B)创建一个Pipe 旋转第二个线程以将该对象写入管道的OutputStream末端。 返回InputStream结束。 实际上,这不能在HttpEntity本身中完成,因为HttpEntity不知道何时不再需要数据流。 (这可以引起人们有根据的猜测,当您到达流的末尾时就已经完成了,但是如果与服务器的连接中途掉线了,您将永远保持管道畅通。)这意味着我最终将解决方法转移到每个建立连接的地方,这是很多结构上的重复。

这些变通办法都不是很好,但是我猜(B)的“狗屎少”,因为它至少不会在传输大对象时使整个应用程序崩溃。

就我所知:

public class WriteLogicEntity extends AbstractHttpEntity {
    private final WriteLogic writeLogic;

    public InputStreamEntity(WriteLogic writeLogic) {
        this(instream, null);
    }

    public InputStreamEntity(WriteLogic writeLogic,
                             ContentType contentType) {
        this.writeLogic = writeLogic;
        if(contentType != null) {
            this.setContentType(contentType.toString());
        }
    }

    @Override
    public boolean isRepeatable() {
        // We could enforce that all WriteLogic be repeatable
        // or add a similar method there, but at least for now,
        // assuming it isn't repeatable is safe.
        return false;
    }

    @Override
    public long getContentLength() {
        // We really don't know.
        return -1L;
    }

    @Override
    public InputStream getContent() throws IOException {
        //TODO: What do we do here?
    }

    @Override
    public void writeTo(OutputStream outstream) throws IOException {
        writeLogic.withOutputStream(outstream);
    }

    @Override
    public boolean isStreaming() {
        return true; //TODO: Verify this choice
    }
}

public interface WriteLogic {
    void withOutputStream(OutputStream stream) throws IOException;
}

现在我想知道getContent()可以抛出UnsupportedOperationException。 当然,在发出请求时,他们还是会使用writeTo() ,对吧? 好吧,我不知道。 即使它可以在一个实验中工作,也不能保证我无法通过某种请求来要求调用getContent()

因此,我想知道是否有人比我更了解此库,所以可以调用它-跳过实现此方法是否安全?

(此getContent()方法似乎不应该包含在API中。或者应该对其进行记录,以至少允许我以某种方式实现它。我打算无论如何都要提交一个错误,因为这样做非常不便在您尝试编写请求时被迫提供InputStream 。)

如果实体内容不能表示为InputStream,则getContent方法可以引发UnsupportedOperationException。 在内部,HttpClient使用writeTo将实体内容流式传输到基础HTTP连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM