W jaki sposób mogę zorganizować zagnieżdżone listy jako JSON za pomocą Jersey? Dostaję tablicę wartości null lub tablicę jednoelementowych słowników zawierających tablicę

Pracuję nad projektem, który wykorzystuje Jersey do konwersji obiektów na JSON. Chciałbym móc pisać listy zagnieżdżone, w ten sposób:

{"data":[["one", "two", "three"], ["a", "b", "c"]]}

Obiekt, który chciałbym przekonwertować na pierwsze reprezentowane dane jako <LinkedList <LinkedList <String> >> i pomyślałem, że Jersey po prostu postąpi dobrze. Powyższe dane zostały wyświetlone jako lista wartości null:

{"data":[null, null]}

Po przeczytaniu, że zagnieżdżone obiekty muszą być opakowane, spróbowałem:

@XmlRootElement(name = "foo")
@XmlType(propOrder = {"data"})
public class Foo
{
    private Collection<FooData> data = new LinkedList<FooData>();

    @XmlElement(name = "data")
    public Collection<FooData> getData()
    {
        return data;
    }

    public void addData(Collection data)
    {
        FooData d = new FooData();
        for(Object o: data)
        {
            d.getData().add(o == null ? (String)o : o.toString());
        }
        this.data.add(d);
    }

    @XmlRootElement(name = "FooData")
    public static class FooData
    {
        private Collection<String> data = new LinkedList<String>();

        @XmlElement
        public Collection<String> getData()
        {
            return data;
        }
    }
}

Ten kod generuje to, co poniżej, co jest bliższe temu, czego chcę:

{"data":[{"data":["one", "two", "three"]},{"data":["a", "b", "c"]}]}

Chcę, aby pierwsze dane były listą list, a nie listą słowników jednoelementowych. Jak to osiągnąć?

Oto mój JAXBContentResolver:

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext>
{
    private JAXBContext context;
    private Set<Class<?>> types;

    // Only parent classes are required here. Nested classes are implicit.
    protected Class<?>[] classTypes = new Class[] {Foo.class};

    protected Set<String> jsonArray = new HashSet<String>(1) {
        {
            add("data");
        }
    };

    public JAXBContextResolver() throws Exception
    {        
        Map<String, Object> props = new HashMap<String, Object>();
        props.put(JSONJAXBContext.JSON_NOTATION, JSONJAXBContext.JSONNotation.MAPPED);
        props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE);
        props.put(JSONJAXBContext.JSON_ARRAYS, jsonArray);
        this.types = new HashSet<Class<?>>(Arrays.asList(classTypes));
        this.context = new JSONJAXBContext(classTyes, props);
    }

    public JAXBContext getContext(Class<?> objectType)
    {
        return (types.contains(objectType)) ? context : null;
    }
}

questionAnswers(3)

yourAnswerToTheQuestion