Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson custom serializer json format

Tags:

json

I want to make my serialized json look like this:

{
 "abc": "smth",
 "def": "smth",
 "ghi": "smth",
}

How can I achieve this with jackson? Here is what I've done so far

@Override
    public void serialize(Value value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        gen.useDefaultPrettyPrinter();
        gen.writeStringField("abc", value.getAaa());
        gen.writeStringField("def", value.getDdd());
        gen.writeStringField("ghi", value.getGgg());
        gen.writeEndObject();
    }

and I get following output

{
"abc" : "smth",
"def" : "smth",
"ghi" : "smth",
}
like image 594
user123454321 Avatar asked Jan 06 '17 15:01

user123454321


2 Answers

To override writeObjectFieldValueSeparator() function you also need to override createInstance method to.

This worked for me:

public class MyPrettyPrinter extends DefaultPrettyPrinter {

    @Override
    public DefaultPrettyPrinter createInstance() {
        return new MyPrettyPrinter();
    }

    @Override
    public void writeObjectFieldValueSeparator(JsonGenerator jg) throws IOException {
        jg.writeRaw(": ");
    }

}

Then just use it as writer of your mapper:

objectMapper.writer(new MyPrettyPrinter()).writeValueAsString(object);

You can find more information about this issue here.

like image 66
Mohsen Avatar answered Sep 28 '22 04:09

Mohsen


As I understand you want to see indents before fields in object. So, to achieve this just swap two lines:

gen.useDefaultPrettyPrinter();
gen.writeStartObject();
...

My test application:

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;

public class Main {

    public static void main(String[] args) throws Exception {
        JsonFactory jsonFactory = new JsonFactory();

        JsonGenerator gen = jsonFactory.createGenerator(System.out);

        gen.useDefaultPrettyPrinter();
        gen.writeStartObject();
        gen.writeStringField("abc", "1");
        gen.writeStringField("def", "2");
        gen.writeStringField("ghi", "3");
        gen.writeEndObject();

        gen.flush();
    }
}

generate the following output:

{
  "abc" : "1",
  "def" : "2",
  "ghi" : "3"
}

Update: About spaces around :. Look at this method. As you can see it is has only two options: <space>:<space> and : So, out of the box you can't do it but you can override this method:

gen.setPrettyPrinter(new DefaultPrettyPrinter() {
    @Override
    public void writeObjectFieldValueSeparator(JsonGenerator jg) throws IOException {
        jg.writeRaw(": ");
    }
});

and use custom pretty printer instead of useDefaultPrettyPrinter. In this case the output will be:

{
  "abc": "1",
  "def": "2",
  "ghi": "3"
}
like image 21
Maxim Avatar answered Sep 28 '22 05:09

Maxim