我正在尝试将带有base64的json流传输到使用Appache HttpComponents的elasticsearch中(据我了解)。
对于json流,我创建了JsonGenerator
,但是它需要“一些” OutputStream
。为了通过Jest发送请求,需要从“ some” InputStreamEntity
创建InputStream
。因此,JsonGenerator
需要用于写入的流,而InputStreamEntity
需要用于读取的流(unknowOutputStream
和unknowInputStream
变量)。流(据我了解)应该相同-但是如何创建它?
乍一看,我可以使用类似ByteArrayInputStream
的方法,但是由于它会将内容填充到byte[]
中,因此所有流数据都将存储到内存中,因此我松散了流式传输。如何创建一个流,该流将仅存储一条数据,直到读取该数据为止。然后保存另一条数据?
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import org.apache.http.HttpHost;
import org.apache.http.entity.InputStreamEntity;
import org.elasticsearch.client.RestClient;
import java.io.DataOutput;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
public class Exmaple {
public static void main (String[] args) throws Exception {
final InputStream inputStream;
final int size;
RestClient restClient = RestClient.builder(new HttpHost("myHost", 443, "https")).build();
final OutputStream unknowOutputStream;
final InputStream unknowInputStream;
final JsonGenerator generator = new JsonFactory().createGenerator(unknowOutputStream);
generator.writeStartObject();
generator.writeFieldName("content");
generator.writeBinary(inputStream, size);
generator.writeEndObject();
restClient.performRequest(
"POST",
"somepath",
Collections.emptyMap(), new InputStreamEntity(unknowInputStream));
}
}
最佳答案
可能有一个使用JDK中的PipedInputStream / PipedOutputStream的解决方案,但是我想您可以更轻松地在HTTPClient的API中从InputStreamEntity
转换为EntityTemplate
。EntityTemplate
是与ContentProducer
一起使用的HTTP实体,并且ContentProducer
的唯一方法是writeTo(OutputStream)
。这样,您将不必桥接输入和输出流。
new EntityTemplate(new ContentProducer(
(outputStream) -> {
final JsonGenerator generator = new JsonFactory().createGenerator(outputStream);
generator.write(...);
}
));
(您可能想创建子类,正确处理异常,...而不是使用lambda。为简单起见,我使用了lambda)。