Джексон десериализует массив с пустым объектом

У меня есть следующий JSON:

{"beans":["{}",{"name":"Will"}]}

и соответствующие классы POJO:

public class BeanA {
    private BeanB[] beans;
    ...getters/setters
}

public class BeanB {
    private String name;
    ...getters/setters
}

Я хотел бы, чтобы Джексон десериализовал BeanA с массивом BeanB, первый элемент был бы просто экземпляром BeanB, а второй - экземпляром BeanB с набором свойств имени.

Я создал исходную строку, сериализовав это:

BeanA beanA = new BeanA();
BeanB beanB = new BeanB();
beanB.setName("Will");
beanA.setBeans(new BeanB[] {new BeanB(), beanB});

Вот моя полная конфигурация для objectMapper:

this.objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

Ошибка, которую я получаю, заключается в следующем:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `BeanB` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{}')

person Will Huang    schedule 04.10.2017    source источник
comment
Этот JSON имеет массив смешанного содержимого, где первый элемент — это строка, а второй — объект. Вы имели в виду {"beans":[{},{"name":"Will"}]} без кавычек вокруг {}?   -  person Andreas    schedule 04.10.2017
comment
В чем проблема? BeanA beanA = this.objectMapper.readValue(json, BeanA.class) не работает?   -  person Luciano van der Veekens    schedule 04.10.2017
comment
Какой у Вас вопрос? Очень простой вызов readValue(), показанный Лучано ван дер Викенс работает нормально, если вы измените "{}" на {}.   -  person Andreas    schedule 04.10.2017
comment
Извините, я понял, что был перехватчик, преобразующий значения json в String, используя String.valueOf   -  person Will Huang    schedule 04.10.2017


Ответы (1)


Используйте ObjectMapper#readValue:

BeanA beanA = new BeanA();
BeanB beanB = new BeanB();
beanB.setName("Will");
beanA.setBeans(new BeanB[] {new BeanB(), beanB});

ObjectMapper om = new ObjectMapper();
om.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
String json = om.writeValueAsString(beanA);
System.out.println(json); 
// output: {"beans":[{},{"name":"Will"}]}

BeanA deserializedBeanA = om.readValue(json, BeanA.class);
System.out.println(deserializedBeanA); 
// output: BeanA{beans=[BeanB{name='null'}, BeanB{name='Will'}]}
person Luciano van der Veekens    schedule 04.10.2017