Whats the Problem?

I ran into a UnrecognizedPropertyException today trying to deserialize the following JSON.

{
  "Places": [{
    "PlaceId": "LOND-sky",
    "PlaceName": "London",
    "CountryId": "UK-sky",
    "RegionId": "",
    "CityId": "LOND-sky",
    "CountryName": "United Kingdom"
  }, {
    "PlaceId": "LHR-sky",
    "PlaceName": "London Heathrow",
    "CountryId": "UK-sky",
    "RegionId": "",
    "CityId": "LOND-sky",
    "CountryName": "United Kingdom"
  }]
}

The Places model was defined as

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class Places {

  private List<Place> places;
}

and the Place model was defined as

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Place {

  String placeId;
  String placeName;
  String countryId;
  String regionId;
  String cityId;
  String countryName;
}

I was using a simplke ObjectMapper like this.

ObjectMapper objectMapper = new ObjectMapper();
Places places = objectMapper.readValue(json, Places.class);

The  UnrecognizedPropertyException stacktrace was as follows.

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Places" (class com.briansdevblog.model.Places), not marked as ignorable (one known property: "placesX"])
 at [Source: (String)"{"Places":[{"PlaceId":"LOND-sky","PlaceName":"London","CountryId":"UK-sky","RegionId":"","CityId":"LOND-sky","CountryName":"United Kingdom"},{"PlaceId":"LHR-sky","PlaceName":"London Heathrow","CountryId":"UK-sky","RegionId":"","CityId":"LOND-sky","CountryName":"United Kingdom"},{"PlaceId":"LGW-sky","PlaceName":"London Gatwick","CountryId":"UK-sky","RegionId":"","CityId":"LOND-sky","CountryName":"United Kingdom"},{"PlaceId":"STN-sky","PlaceName":"London Stansted","CountryId":"UK-sky","RegionId":""[truncated 855 chars]; line: 1, column: 12] (through reference chain: com.briansdevblog.model.Places["Places"])
  at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
  at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:822)
  at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1152)
  at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
  at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
  at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
  at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
  at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
  at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)

Solution

If you look at the JSON sample above, you’ll see that the attributes are uppercased while the member variables on the Place and Places models are lowercased. I don’t have control of the API so I can’t change the case of the JSON attributes. As a workaround, you can configure the ObjectMapper to tell Jackson to accept case insensitive properties as follows.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);