Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to create an InputStream from a Jackson JsonNode?

I would like to find the most clever way to create an InputStream from a JsonNode, of the Java library Jackson.

Until now I have done:

IOUtils.toInputStream(jsonNode.toString());

But this way converts the JsonNode into a String before creating the InputStream.

ex of need:

org.apache.http.entity.InputStreamEntity entity = new InputStreamEntity(IOUtils.toInputStream(jsonNode.toString()));
like image 443
Pleymor Avatar asked Sep 23 '16 12:09

Pleymor


1 Answers

  1. In most cases JSON is written as UTF-8 and you can save some memory, if you directly generate byte array using ObjectMapper.

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode json = ...; 
    byte[] bytes = objectMapper.writeValueAsBytes(json);
    

    Specifically, Apache HTTP client provides ByteArrayEntity for use with byte array. For other uses, there is a ByteArrayInputStream.

    Of course, ObjectMapper should be created only once and reused.

  2. If you really want JSON to be written in a streaming manner, it is possible to use a pair of PipedInputStream and PipedOutputStream, however, as JavaDoc states

    Typically, data is read from a PipedInputStream object by one thread and data is written to the corresponding PipedOutputStream by some other thread. Attempting to use both objects from a single thread is not recommended, as it may deadlock the thread.

    Example:

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode json = ...; 
    
    PipedInputStream in = new PipedInputStream();
    
    new Thread(() -> {
        try {
            IOUtils.copy(in, System.out);
        } catch (IOException e) {
            ...
        }
    }).start();
    
    try (
        PipedOutputStream out = new PipedOutputStream(in);
        JsonGenerator gen = objectMapper.getFactory().createGenerator(out);
    ) {
        gen.writeTree(json);
    } catch (IOException e) {
        ...
    }
    
like image 156
Konstantin Pelepelin Avatar answered Oct 30 '22 09:10

Konstantin Pelepelin