2017-09-28 1 views
0

Ich versuche, json mit base64 in elasticsearch zu streamen, die Appache HttpComponents verwendet (wie ich es verstehe).Wie Stream JSON Inhalt von Jackson zu org.apache.http.entity.InputStreamEntity?

Für JSON Stream ich erstellt JsonGenerator, aber es braucht "einige" OutputStream. Um eine Anfrage über Jest zu senden, müssen Sie InputStreamEntity von "einige" InputStream erstellen. So JsonGenerator benötigt Strom zum Schreiben und InputStreamEntity Stream zum Lesen (unknowOutputStream und unknowInputStream Variablen). Der Stream (wie ich es verstehe) sollte der gleiche sein - aber wie schafft man das?

Auf den ersten Blick könnte ich etwas wie ByteArrayInputStream verwenden, aber damit verliere ich Streaming, weil es Inhalte in byte[] auffüllen wird, so dass alle Stream-Daten im Speicher gespeichert werden. Wie erstelle ich einen Stream, der nur ein Stück Daten speichert, bis diese Daten gelesen werden. Und dann noch ein Stück Daten?

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)); 
    } 
} 

Antwort

1

Es kann eine Lösung sein, einen PipedInputStream/PipedOutputStream aus dem JDK verwenden, aber ich denke, wäre es einfacher für Sie, InputStreamEntity-EntityTemplate in Httpclient API swicth.

EntityTemplate ist ein HTTP-Einheit, die mit einem ContentProducer, und die einzige Methode des ContentProducer ist writeTo(OutputStream) funktioniert. Auf diese Weise müssten Sie Input- und Output-Streams nicht überbrücken.

new EntityTemplate(new ContentProducer(
    (outputStream) -> { 
     final JsonGenerator generator = new JsonFactory().createGenerator(outputStream); 
     generator.write(...); 
    } 
)); 

(Sie können Unterklassen erstellen möchten, richtig mit Ausnahmen behandeln, ... statt einer Lambda zu verwenden. Ich habe eines der Einfachheit halber).

Verwandte Themen