Jackson JSON Deserialization: array elements in ea

2020-06-09 09:24发布

问题:

I am using Jackson and would like to pretty-print JSON such that each element in arrays goes to each line, like:

{
  "foo" : "bar",
  "blah" : [
    1,
    2,
    3
  ]
}

Setting SerializationFeature.INDENT_OUTPUT true only inserts newline characters for object fields, not array elements, printing the object in this way instead:

{
  "foo" : "bar",
  "blah" : [1, 2, 3]
}

Does anyone know how to achieve this? Thanks!

回答1:

You could extend the DefaultPrettyPrinter and override the methods beforeArrayValues(…) and writeArrayValueSeparator(…) to archieve the desired behaviour. Afterwards you have to add your new Implementation to your JsonGenerator via setPrettyPrinter(…).



回答2:

Thanks to the helpful hints, I was able to configure my ObjectMapper with desired indentation as follows:

private static class PrettyPrinter extends DefaultPrettyPrinter {
    public static final PrettyPrinter instance = new PrettyPrinter();

    public PrettyPrinter() {
        _arrayIndenter = Lf2SpacesIndenter.instance;
    }
}

private static class Factory extends JsonFactory {
    @Override
    protected JsonGenerator _createGenerator(Writer out, IOContext ctxt) throws IOException {
        return super._createGenerator(out, ctxt).setPrettyPrinter(PrettyPrinter.instance);
    }
}

{
    ObjectMapper mapper = new ObjectMapper(new Factory());
    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
}


回答3:

If you don't want to extend DefaultPrettyPrinter you can also just set the indentArraysWith property externally:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
prettyPrinter.indentArraysWith(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE);

String json = objectMapper.writer(prettyPrinter).writeValueAsString(object);


回答4:

The answer thankfully provided by OP shows a way for obtain a single-array-element-per-line formatted JSON String from writeValueAsString. Based on it here a solution to write the same formatted JSON directly to a file with writeValue with less code:

private static class PrettyPrinter extends DefaultPrettyPrinter {
    public static final PrettyPrinter instance = new PrettyPrinter();

    public PrettyPrinter() {
        _arrayIndenter = Lf2SpacesIndenter.instance;
    }
}

{
    ObjectMapper mapper = new ObjectMapper();
    ObjectWriter writer = mapper.writer(PrettyPrinter.instance);
    writer.writeValue(destFile, objectToSerialize);
}


回答5:

Mapper can be configured (jackson-2.6) with:

ObjectMapper mapper = ...
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
prettyPrinter.indentArraysWith(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE);
mapper.setDefaultPrettyPrinter(prettyPrinter);

//use mapper 


回答6:

try out JSON Generator...

API Reference
good example