7

My Controller returns a list of MyObj objects (using @ResponseBody)

public MyObj 
{
   int a;
   int b;
}

The return JSON looks like this:

[{"a":1,"b":2},{"a":2,"b":2}]

I would like to wrap this JSON so it will return something like:

{ "data": [{"a":1,"b":2},{"a":2,"b":2}]}

From what i read i need to enable SerializationConfig.Feature.WRAP_ROOT_VALUE or (?) use @JsonRootName("data") on top of my controller.

Also tried the @XmlRootElement, nothing seems to work. Any idea what is the right way to wrap the list of objects with a root name?

user1782427
  • 770
  • 1
  • 8
  • 19
  • 1
    Did you ever figure out how to do this? I figured out a round about way by creating a map of lists, and then letting ObjectMapper do it's thing, but that isn't so elegant. I am thinking there's a better way to do this. Did you figure it out? – Seagull Apr 13 '13 at 00:31
  • Does this answer your question? [Use class name as root key for JSON Jackson serialization](https://stackoverflow.com/questions/2435527/use-class-name-as-root-key-for-json-jackson-serialization) – WorldSEnder Dec 12 '21 at 22:50

2 Answers2

11

It sounds like you're talking about putting @JsonRootName on the list rather than the object, which won't accomplish what you're trying to do.

If you would like to use @JsonRootName you'll want to enable SerializationFeature.WRAP_ROOT_VALUE like you mentioned above and add the annotation to the class:

@JsonRootName("data")
public MyObj {
    int a;
    int b;
}

This will wrap the objects themselves, not the list:

{
    "listName": [
        {
            "data": {"a":1, "b":2}
        },
        {
            "data": {"a":2, "b":2}
        }
    ]
}

If you want to wrap the list in an object, perhaps creating a generic object wrapper is the best solution. This can be accomplished with a class like this:

public final class JsonObjectWrapper {
    private JsonObjectWrapper() {}

    public static <E> Map<String, E> withLabel(String label, E wrappedObject) {
        return Collections.singletonMap(label, wrappedObject);
    }
}

Then before you send your list back with the response, just wrap it in JsonObjectWrapper.withLabel("data", list) and Jackson takes care of the rest.

Sam Berry
  • 7,394
  • 6
  • 40
  • 58
1

This should do the job:

    List<MyObj> myList;
    
    ObjectWriter ow = mapper.writer()
            .with(SerializationFeature.WRAP_ROOT_VALUE)
            .withRootName("data");
    
    System.out.println(ow.writeValueAsString(myList));
Tomasz Gawel
  • 8,379
  • 4
  • 36
  • 61