0

I am a beginner of Jackson. How can I create a JSON message like this using Java?

{
    "name": "John",
    "age": "40",
    "family": {
        "parents_name": [
            "David",
            "Susan"
        ],
        "children": "yes",
        "children_names": [
            "Peter",
            "Mary"
        ]
    }
}
Damodaran
  • 10,882
  • 10
  • 60
  • 81
user2940105
  • 31
  • 1
  • 3
  • Did you try to check the docs? http://wiki.fasterxml.com/JacksonInFiveMinutes – fujy Nov 06 '13 at 04:18
  • Check here http://stackoverflow.com/questions/16974474/creating-a-json-object-using-jackson and http://stackoverflow.com/questions/11110446/create-simple-json-structure-using-jackson – Jayasagar Nov 06 '13 at 04:23

3 Answers3

1

Create a Person class in Java, with properties such as getName(), getAge() and so on. Then Jackson can create that JSON for you automatically, from your Person object.

Sualeh Fatehi
  • 4,700
  • 2
  • 24
  • 28
1

The easiest way to do this for a beginner is to eliminate unnecessary nesting and rely on Jackson's default object binding.

You would create a class like this:

public class Person {
    private String name;
    private int age;
    private List<String> parentNames;
    private List<String> childrenNames;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getParentNames() {
        return parentNames;
    }

    public void setParentNames(List<String> parentNames) {
        this.parentNames = parentNames;
    }

    public List<String> getChildrenNames() {
        return childrenNames;
    }

    public void setChildrenNames(List<String> childrenNames) {
        this.childrenNames = childrenNames;
    }
}

Then you can instantiate a Person from JSON like this:

Person p = ObjectMapper.readValue(jsonString, Person.class);

Note that the JSON you have in your example won't work with this object for three reasons:

  • The Person class has no Family object. I felt that adds unnecessary complexity. If you want that, create a separate Family class, and Person would contain a Family member (no pun intended).
  • I don't have a boolean for children because that can be deduced from the length of the childrenNames list.
  • The JSON will need to have childrenNames and parentNames rather than children_names and parents_name. If you want those, add @JsonProperty with the desired property names on the getters and setters for those values.
Vidya
  • 29,932
  • 7
  • 42
  • 70
  • * How about if age is optional and sometimes I don't want to include the age in the JSON message? * Is there a simpler way other than the Family class? Because I need to create many JSON messages with different nested values. In this way I have to create many different inner-class like Family. I am restricted to use Jackson this time – user2940105 Nov 06 '13 at 04:58
  • Yes, there is a simpler way than the `Family` class. My answer haha. A major premise of my answer is that the `Family` class is unnecessary. That's why I don't have one in my code sample. As for an optional age, just have an `age` member. If it isn't in the JSON, the setter won't be called. – Vidya Nov 06 '13 at 05:05
  • I tried not to assign any values to age but the result is a JSON message with "age":null. In fact I don;t want to see the "age" – user2940105 Nov 06 '13 at 05:12
  • We are starting to get off-topic and do the long thread thing they don't like here at Stack Overflow. The solution for this is `@JsonInclude(Include.NON_NULL)`. But just check the Jackson documentation or other questions on Stack Overflow as more of your questions arise. I am fairly certain all your questions have been answered before. – Vidya Nov 06 '13 at 05:16
0

I gather from your comments to Vidya's solution that your looking for more flexibility than you get can get with the default binding.

Jackson allows you to create your own custom serializer. For example:

public class Person {
    private String name;
    private int age;
    private List<String> parentsName;
    private List<String> childrenNames;

    public Person(String name, List<String> parentsName) {
        this(name, parentsName, -1, Collections.<String>emptyList());
    }

    public Person(String name, List<String> parentsName, int age) {
        this(name, parentsName, age, Collections.<String>emptyList());
    }

    public Person(String name, List<String> parentsName, int age, List<String> childrenNames) {
        this.name = name;
        this.age = age;
        this.parentsName = parentsName;
        this.childrenNames = childrenNames;
    }

    private void serialize(JsonGenerator generator, SerializerProvider arg2) throws IOException {
        generator.writeStartObject();

        generator.writeObjectField("name", name);

        if (age >= 0)
            generator.writeNumberField("age", age);

        // start family subset
        generator.writeObjectFieldStart("family");

        generator.writeArrayFieldStart("parents_name");
        for (String parent : parentsName) { 
            generator.writeObject(parent);
        }
        generator.writeEndArray();

        generator.writeObjectField("children", (childrenNames.isEmpty() ? "no" : "yes"));

        generator.writeArrayFieldStart("children_names");

        for (String child : childrenNames) {
            generator.writeObject(child);
        }
        generator.writeEndArray();

        generator.writeEndObject();
        // end family subset

        generator.writeEndObject();
    }

    public static JsonSerializer<Person> createJsonSerializer() { 
        return new JsonSerializer<Person>() {
            @Override
            public void serialize(Person me, JsonGenerator generator, SerializerProvider arg2) throws IOException, JsonProcessingException {
                me.serialize(generator, arg2);
            }            
        };
    }

    public static void main(String[] args) throws IOException {
        List<String> parentsName = Arrays.<String>asList("David", "Susan");
        List<String> childrenNames = Arrays.<String>asList("Peter", "Mary");
        Person person = new Person("John", parentsName, 40, childrenNames);

        ObjectMapper mapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule("PersonModule", new Version(1, 0, 0, null));
        simpleModule.addSerializer(Person.class, Person.createJsonSerializer());

        // pretty output for debugging
        mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); 
        mapper.registerModule(simpleModule);

        System.out.println("Person json: ");
        System.out.println(mapper.writeValueAsString(person));

    }
}

This gives you increased flexibility in two ways:

  • You can apply conditional logic in serialization

  • You can have multiple custom serializers

The downsides are fairly obvious

  • More complicated

  • More time to implement. The default bindings were almost free. This solution is not.

JohnC
  • 698
  • 7
  • 12