Джексон: сериализация пользовательских коллекций в JSON - PullRequest
7 голосов
/ 17 октября 2010

Я пытаюсь json-сериализовать класс MyRootClass со свойством, которое является коллекцией элементов второго класса MyClass:

public class MyRootClass {
   private List<MyInterface> list = new ArrayList<MyInterface>();
   // getter / setter
}

public class MyClass implements MyInterface {
   private String value = "test";    
   // getter / setter
}

Следующий код:

MyRootClass root = new MyRootClass();
root.getList().add(new MyClass());
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(System.out, root);

Создает этот вывод JSON:

{"list": [ {"value":"test"} ] }

вместо того, что мне нужно, каждый объект в коллекции сериализуется с именем:

{"list": [ {"myclass": {"value":"test"}} ] }

Есть ли способ добиться этого с помощью Джексона? Я думал о написании собственного сериализатора, но я не нашел ничего связанного с коллекцией объектов.

Ответы [ 3 ]

7 голосов
/ 18 октября 2010

Это зависит от того, что именно вы хотите достичь с именем; но да, это можно сделать, если вы хотите включить «myclass» в эту информацию о типе (или можете действовать так, как если бы она использовалась; если вы не используете Джексона для десериализации, это не имеет значения).

Если это так, вы должны аннотировать MyInterface:

@JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT)

и MyClass с:

@JsonTypeName("myclass")

(если вы не укажете это, именем по умолчанию будет безусловное имя класса)

@JsonTypeInfo выше определяет, что следует использовать имя типа (вместо имени класса Java или пользовательского метода), и включение выполняется с использованием объекта-оболочки (альтернативы - массив-обертка и свойство as-property)

Итак, вы должны увидеть ожидаемый результат.

1 голос
/ 18 августа 2011

Вы можете использовать вспомогательный объект следующим образом:

public static class MyObject {
    public int i;
    public MyObject(int i) { this.i = i; }
    public MyObject() {}
}

@JsonDeserialize(contentAs=MyObject.class)
public static class MyHelperClass extends ArrayList<MyObject> {

}

@Test
public void testCollection() throws JsonGenerationException, JsonMappingException, IOException {
    final Collection<MyObject> l = new ArrayList<MyObject>();
    l.add(new MyObject(1));
    l.add(new MyObject(2));
    l.add(new MyObject(3));

    final ObjectMapper mapper = new ObjectMapper();

    final String s = mapper.writeValueAsString(l);
    final Collection<MyObject> back = mapper.readValue(s, MyHelperClass.class);

}
1 голос
/ 17 октября 2010

Вы хотите включить имя класса в вывод.Это не так, как ведут себя сериализаторы json - они включают только имена полей.

Что вы можете сделать, это ввести другой класс.

class MyClass implements MyInterface {
    private MyOtherClass myclass;
}

class MyOtherClass {
    private String value = "test";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...