Джексон: пользовательская коллекция сериализации к JSON

StackOverflow https://stackoverflow.com/questions/3954265

  •  08-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь JSON-Serialize класс 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"}} ] }

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

Это было полезно?

Решение

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

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

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

и MyClass с:

@JsonTypeName("myclass")

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

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

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

Другие советы

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

Что вы можете сделать, это представить еще один класс.

class MyClass implements MyInterface {
    private MyOtherClass myclass;
}

class MyOtherClass {
    private String value = "test";
}

Вы можете использовать вспомогательный объект, как это:

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);

}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top