javaarraysjsonspringjackson2

deserialize a json array into a java object holding list


I'm getting a json array holding objects looking like this:

[
    {
        "id": "1",
        "name": "some name",
        "url": "some url",
        "active": true
    }, {
        "id": "2",
        "name": "some other name",
        "url": "some other url",
        "active": true
    }
]

Now, I want to be able to deserialize that array into a java object holding a list of the objects in the array. I have made a custom deserializer looking like this:

public class ListSerializer extends JsonDeserializer<List<Provider>>{

    private static final long serialVersionUID = 9114152571639338391L;

    @Override
    public List<Provider> deserialize(JsonParser jsonParser, 
    DeserializationContext arg1) throws IOException, JsonProcessingException {
    // TODO Auto-generated method stub
    final ObjectCodec objectCodec = jsonParser.getCodec();
    final JsonNode listOrObjectNode = objectCodec.readTree(jsonParser);
    final List<Provider> result = new ArrayList<Provider>();
    for (JsonNode node : listOrObjectNode) {
      result.add(objectCodec.treeToValue(node, Provider.class));
    }
      return result;
    }
}

And the class holding the list looks like this:

public class ProviderList {

    @JsonDeserialize(using = ListSerializer.class)
    private List<Provider> providerList;

     public List<Provider> getProviderList() {
      return providerList;
    }

    public void setProviderList(final List<Provider> providerList) {
      this.providerList = providerList;
     }
}

I am obviously doing something wrong, because I'm getting this error:

Can not deserialize instance of com.wirelesscar.trailser.v1_0.domain.ProviderList out of START_ARRAY token at [Source: [{"id":"1","name":"Posttrack","url":"http:\dev.posttrack.com","active":true},{"id":"2","name":"Trackunit","url":"http:\dev.trackunit.com","active":true}]; line: 1, column: 1]

How can I do this properly?


Solution

  • You can deserialize directly to a list by using the TypeReference wrapper.

    @Data
    public class Provider {
        private Long id;
        private String name;
        private String url;
        private boolean active;
    }
    
    @Data
    public class ProviderList {
        List<Provider> providerList;
    }
    
    public class JsonTest {
    
        @Test
        public void  test() {
            String json = "[{\n" +
                    "        \"id\": \"1\",\n" +
                    "        \"name\": \"some name\",\n" +
                    "        \"url\": \"some url\",\n" +
                    "        \"active\": true\n" +
                    "    }, {\n" +
                    "        \"id\": \"2\",\n" +
                    "        \"name\": \"some other name\",\n" +
                    "        \"url\": \"some other url\",\n" +
                    "        \"active\": true\n" +
                    "    }\n" +
                    "]";
    
            ObjectMapper mapper = new ObjectMapper();
            try {
                List<Provider> providerList = mapper.readValue(json, new TypeReference<List<Provider>>(){});
                for (Provider provider : providerList) {
                    System.out.println(provider);
                }
    
                ProviderList list = new ProviderList();
                list.setProviderList(providerList);
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }