2

I have the following JSON:

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

and the corresponding POJO classes:

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

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

I would like jackson to deserialize to BeanA with an array of BeanBs, the first element would be just an instance of BeanB and the second with be an instance of BeanB with the name property set.

I've created the original string by serializing this:

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

Here's my full configuration for 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);

The error I get is this:

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 ('{}')
Will Huang
  • 325
  • 7
  • 15
  • That JSON has an array of mixed content, where first element is a string and second element is an object. Did you mean `{"beans":[{},{"name":"Will"}]}`, without the quotes around `{}`? – Andreas Oct 04 '17 at 18:14
  • 1
    What's the issue here? Does `BeanA beanA = this.objectMapper.readValue(json, BeanA.class)` not work? – Luciano van der Veekens Oct 04 '17 at 18:16
  • What is your question? The very simple [`readValue()` call shown by Luciano van der Veekens](https://stackoverflow.com/questions/46571451/jackson-deserialize-array-with-empty-object-as-object#comment80096702_46571451) works fine, assuming you change `"{}"` to `{}`. – Andreas Oct 04 '17 at 18:19
  • Sorry, I realized that there was an interceptor converting the values of the json into String using String.valueOf – Will Huang Oct 04 '17 at 19:00

1 Answers1

2

Use 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'}]}
Luciano van der Veekens
  • 6,307
  • 4
  • 26
  • 30