我可以跳过实施 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
端。 Return InputStream
结束。这实际上无法在 HttpEntity
本身中完成,因为 HttpEntity
不知道何时不再需要数据流。 (它可以做出有根据的猜测,当您到达流的末尾时它就完成了,但是如果与服务器的连接在中途断开,您将永远打开管道。)这意味着我最终将解决方法移动到每个建立连接的地方,这是很多结构重复。
这些解决方法都不是很好,但我猜 (B) 是 "less shit" 因为它至少不会在传输大对象时使整个应用程序崩溃。
据我所知:
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 连接。
我打算将结构化数据写入通过 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
端。 Return InputStream
结束。这实际上无法在 HttpEntity
本身中完成,因为 HttpEntity
不知道何时不再需要数据流。 (它可以做出有根据的猜测,当您到达流的末尾时它就完成了,但是如果与服务器的连接在中途断开,您将永远打开管道。)这意味着我最终将解决方法移动到每个建立连接的地方,这是很多结构重复。
这些解决方法都不是很好,但我猜 (B) 是 "less shit" 因为它至少不会在传输大对象时使整个应用程序崩溃。
据我所知:
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 连接。