Explain Codes LogoExplain Codes Logo

Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

java
custom-deserializer
json-structure
deserialization
Nikita BarsukovbyNikita Barsukov·Jan 31, 2025
TLDR

The error "Can not deserialize instance of java.util.ArrayList out of START_OBJECT token" implies misalignment between the received JSON structure (an object) and the expected Java type (a list). Here's how to fix it:

JSON is an array: Ensure that your Java type corresponds to a List or ArrayList.

ObjectMapper mapper = new ObjectMapper(); // When JSON gives you an array, make a List! List<MyClass> myList = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>() {});

JSON is an object holding an array: Map it to a Java class with an equivalent list field.

class Container { public List<MyClass> items; } ObjectMapper mapper = new ObjectMapper(); // If JSON provides a container for your array, embrace it! Container container = mapper.readValue(jsonInput, Container.class);

The nasty pitfall with complex JSON structures is the uncertainty of incoming data composition. Single objects masquerading as arrays or an elaborate nesting structure can disrupt peaceful deserialization. But do not fear, for we have remedies!

Custom Deserializer: The Benevolent Dictator

When JSON rebelliously defies conventional formats, bring in your custom deserializer to establish law and order.

class MyCustomDeserializer extends JsonDeserializer<List<MyClass>> { @Override public List<MyClass> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Because sometimes we ought to take matters in our own hands! } }

One is not the loneliest number: Arrayifying Single Entries

Sometimes, JSON mischievously sends a single lonesome object when we expect a vibrant array. Tame this JSON wilding by turning on ACCEPT_SINGLE_VALUE_AS_ARRAY in ObjectMapper.

ObjectMapper mapper = new ObjectMapper(); mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); // When JSON innocently sends a singleton, we deftly turn it into a socialite! List<MyClass> myList = mapper.readValue(singleObjectJsonInput, new TypeReference<List<MyClass>>() {});

Sherlock Holmes Diagnostics

Playing detective with detailed exception stacks can clue us into JSON misdemeanors. Crime scene analysis often reveals JSON misbehavior at erroneous line and column numbers.

Threading the Needle: Troubleshooting Scenarios

Let's gear up as surgeons and delve deep into the JSON patient to diagnose and rectify ailing scenarios.

Scenario: JSON Imposter

A JSON "monster" { "item": {...} } might assert itself as an array [ {...}, {...} ]. Assuming control over the client-side, mend the JSON structure. If server-side power is at hand, battle the beast by refactoring the server code to adapt to the JSON shape.

Scenario: Lost in Translation

JSON property names lost in the wilderness of Java field names need an @JsonProperty beacon to map them to their right destinations.

class MyClassWrapper { @JsonProperty("my_items") private List<MyClass> myClassList; // When JSON and Java are a language apart! }

Scenario: Dynamic Diversity

When a slippery JSON oscillates among array, object, and unicorn types, go with the flow and create a wrapper POJO mirroring its capricious habits.

Scenario: Polymorphic Performance

For a shape-shifting JSON ensemble featuring various subclasses, conduct with @JsonTypeInfo and @JsonSubTypes to perfectly synchronize the polymorphic orchestra.

@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = SubClassA.class, name = "a"), @JsonSubTypes.Type(value = SubClassB.class, name = "b") }) // When JSON stages a diverse polymorphic performance! public abstract class BaseClass {}

Visualization

Think of JSON objects as chests (📦) filled with treasures (data) and lists (arrays) like rows of neatly arranged coins (🪙🪙🪙).

📦: { "gold": "999.9" } 🪙🪙🪙: ['gold1', 'gold2']

Cramming a treasure chest into a row of coins brings chaos, not order. Ensure that chest treasures get placed into the right coin row, and everything falls into place.

Fortifying the deserialization stronghold

Leading the steadfast ObjectMapper into battle and understanding your JSON enemy's strategy is the key to conquering deserialization woes. Here are a few more armory elements:

  • Always scout your JSON structure before plunging into deserialization battle.
  • Deploy Jackson's annotations to strategically lead the mapping process.
  • Use the instanceof operator as your safety harness when dealing with the fierce dragon of dynamic JSON types.
  • Be watchful at the List vs. ArrayList frontier, as specific battle formations can change the tide of war.