Why am I not able to deserialize an array of objects by unwrapping the root node?
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonRootName;
import org.junit.Assert;
import org.junit.Test;
public class RootNodeTest extends Assert {
@JsonRootName("customers")
public static class Customer {
public String email;
}
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customers\":[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\"}]}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
List<Customer> customers = Arrays.asList(mapper.readValue(json, Customer[].class));
System.out.println(customers);
}
}
I've been digging through the Jackson documentation and this is what I could figure out but upon running it, I get the following error:
A org.codehaus.jackson.map.JsonMappingException has been caught, Root name 'customers' does not match expected ('Customer[]') for type [array type, component type: [simple type, class tests.RootNodeTest$Customer]] at [Source: java.io.StringReader@49921538; line: 1, column: 2]
I would like to accomplish this without creating a wrapper class. While this is an example, I don't want to create unnecessary wrapper classes only for unwrapping the root node.
Create an ObjectReader to configure the root name explicitly:
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customers\":[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\"}]}";
ObjectReader objectReader = mapper.reader(new TypeReference<List<Customer>>() {})
.withRootName("customers");
List<Customer> customers = objectReader.readValue(json);
assertThat(customers, contains(customer("[email protected]"), customer("[email protected]")));
}
(btw this is with Jackson 2.5, do you have a different version? I have DeserializationFeature rather than DeserializationConfig.Feature)
It seems that by using an object reader in this fashion, you don't need to globally configure the "unwrap root value" feature, nor use the @JsonRootName
annotation.
Note also that you can directly request a List<Customer>
rather than going through an array- the type given to ObjectMapper.reader
works just like the second parameter to ObjectMapper.readValue
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments