Java Jackson JsonGenerator: Creating wrapper JSON to list results in java.lang.IllegalStateException: No ObjectCodec defined

386 Views Asked by At

I have a Java method that gets the list of customer information in JSON format as InputStream. I would like to add the wrapper to this JSON, which is being created using the Jackson JsonGenerator. When I try to add the customerList as a tree then I get the error java.lang.IllegalStateException: No ObjectCodec defined

Following is the customer list thats obtained by my method:

[
  {
    "name":"Batman",
    "age":45,
    "city":"gotham"
  },
  {
    "name":"superman",
    "age":50,
    "city":"moon"
  }
]

I would like to add a wrapper and make it like this:

{
  "isA": "customerDocument",
  "createdOn": "2022-10-10T12:29:43",
  "customerBody": {
    "customerList": [
      {
        "name": "Batman",
        "age": 45,
        "city": "gotham"
      },
      {
        "name": "superman",
        "age": 50,
        "city": "moon"
      }
    ]
  }
}

Following is my method for doing this:

private InputStream generateJsonDocumentWrapper(final InputStream inputEventList) throws IOException {
      final PipedInputStream jsonDocumentWriter = new PipedInputStream();
      final PipedOutputStream out = new PipedOutputStream(jsonDocumentWriter);
      final ExecutorService executorService = Executors.newWorkStealingPool();
      final JsonParser jsonParser = new JsonFactory().createParser(inputEventList);
      final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()).enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
      jsonParser.setCodec(objectMapper);
      final JsonNode node = jsonParser.readValueAsTree();
      System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(node));

      executorService.execute( () -> {
          try{
              try (JsonGenerator jsonGenerator = jsonfactory.createGenerator(out)) {
                  jsonGenerator.writeStartObject();
                  jsonGenerator.writeStringField("type", "customerDocument");
                  jsonGenerator.writeStringField("creationDate", Instant.now().toString());
                  jsonGenerator.writeFieldName("customerBody");
                  jsonGenerator.writeStartObject();
                  jsonGenerator.writeFieldName("customerList")
                  jsonGenerator.writeRaw(":")
                  jsonGenerator.writeTree(node); // works fine with jsonGenerator.writeRawValue(IOUtils.toString(inputEventList, StandardCharsets.UTF_8));
                  jsonGenerator.writeEndObject();
                  jsonGenerator.writeEndObject();
                  jsonGenerator.flush();
              } catch (IOException ex) {
                  throw new IOException();
              }
          }catch (Exception ex) {
              ex.printStackTrace();
          }
      });

    System.out.println("Wrpper DOCUMENT : " + IOUtils.toString(jsonDocumentWriter, StandardCharsets.UTF_8));
    return jsonDocumentWriter;
  }

If I convert the InputStream directly to String then its working fine but I dont want to use the IOUtils.toString(inputEventList, StandardCharsets.UTF_8) so I am trying to read as tree but this results in the following error:

java.lang.IllegalStateException: No ObjectCodec defined

        at com.fasterxml.jackson.core.base.GeneratorBase.writeTree(GeneratorBase.java:403)
        at my.package.CustomerWrapperGenerator.lambda$generateJsonDocumentWrapper$4(CustomerWrapperGenerator.java:319)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)

1

There are 1 best solutions below

0
BATMAN_2008 On

I was able to make it work by following:

private InputStream generateJsonDocumentWrapper(final InputStream inputEventList) throws IOException {
      final JsonFactory jsonfactory = new JsonFactory();
      final PipedInputStream jsonDocumentWriter = new PipedInputStream();
      final PipedOutputStream out = new PipedOutputStream(jsonDocumentWriter);
      final ExecutorService executorService = Executors.newWorkStealingPool();
      final JsonParser jsonParser = new JsonFactory().createParser(inputEventList);
      final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()).enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
      jsonParser.setCodec(objectMapper);
      jsonfactory.setCodec(objectMapper);
      final JsonNode node = jsonParser.readValueAsTree();

      executorService.execute( () -> {
          try{
              try (JsonGenerator jsonGenerator = jsonfactory.createGenerator(out)) {
                  jsonGenerator.writeStartObject();
                  jsonGenerator.writeStringField("type", "customerDocument");
                  jsonGenerator.writeStringField("creationDate", Instant.now().toString());
                  jsonGenerator.writeFieldName("customerBody");
                  jsonGenerator.writeStartObject();
                  jsonGenerator.writeFieldName("customerList")
                  jsonGenerator.writeTree(node);
                  jsonGenerator.writeEndObject();
                  jsonGenerator.writeEndObject();
                  jsonGenerator.flush();
              } catch (IOException ex) {
                  throw new IOException();
              }
          }catch (Exception ex) {
              ex.printStackTrace();
          }
      });

    System.out.println("Wrpper DOCUMENT : " + IOUtils.toString(jsonDocumentWriter, StandardCharsets.UTF_8));
    return jsonDocumentWriter;
  }