178

Given the following .json file:

[ { "name" : "New York", "number" : "732921", "center" : [ "latitude" : 38.895111, "longitude" : -77.036667 ] }, { "name" : "San Francisco", "number" : "298732", "center" : [ "latitude" : 37.783333, "longitude" : -122.416667 ] } ] 

I prepared two classes to represent the contained data:

public class Location { public String name; public int number; public GeoPoint center; } 

...

public class GeoPoint { public double latitude; public double longitude; } 

In order to parse the content from the .json file I use Jackson 2.2.x and prepared the following method:

public static List<Location> getLocations(InputStream inputStream) { ObjectMapper objectMapper = new ObjectMapper(); try { TypeFactory typeFactory = objectMapper.getTypeFactory(); CollectionType collectionType = typeFactory.constructCollectionType( List.class, Location.class); return objectMapper.readValue(inputStream, collectionType); } catch (IOException e) { e.printStackTrace(); } return null; } 

As long as I leave out the center property all content can be parsed. However, when I try to parse the geo-coordinates I end up with the following error message:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of
com.example.GeoPoint out of START_ARRAY token at [Source: android.content.res.AssetManager$AssetInputStream@416a5850; line: 5, column: 25]
(through reference chain: com.example.Location["center"])

4
  • why are you using jackson if you can simply parse it with json parser Commented Oct 12, 2013 at 10:38
  • 5
    Your JSON string is malformed, the type of center is an array of invalid objects. Try to replace [ and ] with { and } in the JSON string around longitude and latitude so they will be objects. Commented Oct 12, 2013 at 10:40
  • 1
    @Katona Thank you. Can you please convert your comment into an answer so I can close the question?! Commented Oct 16, 2013 at 15:47
  • 1
    I had the same error, but because I had used a LocalDate class. Once i added the missing JavaTimeModule with "mapper.registerModule(new JavaTimeModule());" , the problem went away. Commented Sep 28, 2020 at 18:52

6 Answers 6

194

JsonMappingException: out of START_ARRAY token exception is thrown by Jackson object mapper as it's expecting an Object {} whereas it found an Array [{}] in response.

This can be solved by replacing Object with Object[] in the argument for geForObject("url",Object[].class). References:

  1. Ref.1
  2. Ref.2
  3. Ref.3
Sign up to request clarification or add additional context in comments.

1 Comment

For Kotliners here is an example: val result: ResponseEntity<Array<BillingType>> = restTemplate.getForEntity(uri, Array<BillingType>::class.java)
100

Your JSON string is malformed: the type of center is an array of invalid objects. Replace [ and ] with { and } in the JSON string around longitude and latitude so they will be objects:

[ { "name" : "New York", "number" : "732921", "center" : { "latitude" : 38.895111, "longitude" : -77.036667 } }, { "name" : "San Francisco", "number" : "298732", "center" : { "latitude" : 37.783333, "longitude" : -122.416667 } } ] 

2 Comments

The same problem I had, but it crazy since in jackson 2.6.3v there was a totally different crazy error, and with 2.9.8v everything worked. Damn it, so these serialization errors are so annoying.
Atul Sharma answer Below looks more relevant for this question. Kindly review and modify. Thanks
20

I sorted this problem as verifying the json from JSONLint.com and then, correcting it. And this is code for the same.

String jsonStr = "[{\r\n" + "\"name\":\"New York\",\r\n" + "\"number\": \"732921\",\r\n"+ "\"center\": {\r\n" + "\"latitude\": 38.895111,\r\n" + " \"longitude\": -77.036667\r\n" + "}\r\n" + "},\r\n" + " {\r\n"+ "\"name\": \"San Francisco\",\r\n" +\"number\":\"298732\",\r\n"+ "\"center\": {\r\n" + " \"latitude\": 37.783333,\r\n"+ "\"longitude\": -122.416667\r\n" + "}\r\n" + "}\r\n" + "]"; ObjectMapper mapper = new ObjectMapper(); MyPojo[] jsonObj = mapper.readValue(jsonStr, MyPojo[].class); for (MyPojo itr : jsonObj) { System.out.println("Val of name is: " + itr.getName()); System.out.println("Val of number is: " + itr.getNumber()); System.out.println("Val of latitude is: " + itr.getCenter().getLatitude()); System.out.println("Val of longitude is: " + itr.getCenter().getLongitude() + "\n"); } 

Note: MyPojo[].class is the class having getter and setter of json properties.

Result:

Val of name is: New York Val of number is: 732921 Val of latitude is: 38.895111 Val of longitude is: -77.036667 Val of name is: San Francisco Val of number is: 298732 Val of latitude is: 37.783333 Val of longitude is: -122.416667 

1 Comment

This fixed the problem I've been having for days, no other answers made sense. For anyone else having the same error. It's worth noting that if your JSON has multiple object in, you need to be returning multiple objects. I had been returning MyObject, where I should have been returning MyObject[]
16

As said, JsonMappingException: out of START_ARRAY token exception is thrown by Jackson object mapper as it's expecting an Object {} whereas it found an Array [{}] in response.

A simpler solution could be replacing the method getLocations with:

public static List<Location> getLocations(InputStream inputStream) { ObjectMapper objectMapper = new ObjectMapper(); try { TypeReference<List<Location>> typeReference = new TypeReference<>() {}; return objectMapper.readValue(inputStream, typeReference); } catch (IOException e) { e.printStackTrace(); } return null; } 

On the other hand, if you don't have a pojo like Location, you could use:

TypeReference<List<Map<String, Object>>> typeReference = new TypeReference<>() {}; return objectMapper.readValue(inputStream, typeReference); 

2 Comments

Thank you for sharing this alternative implementation. Can you tell if there are advantages or disadvantages with using CollectionType vs. TypeReference?
TypeReference syntax is far shorter than the other. Not sure, if in some cases there could be a counter-indication related to the type erasure... but in my world TypeReference is just easier to use and understand.
0

If you are working with web services, the problem could be in the body value. You could send the value with an array in the following way

enter image description here

And obtain the error

enter image description here

To fix it, you must change the body correctly as an object

enter image description here

Greetings

Comments

-1

For instance:

data class

data class ToDo( var id: Int, var text: String?, var completed: Boolean?) {} 

Above deserialization error thrown when you use ToDo::class.java but not Array::class.java for json list

DOEST NOT WORK

 private val mapper = ObjectMapper().registerKotlinModule() ..... val todo= mapper.readValue(response.body(), ToDo::class.java) 

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type com.example.api.dto.ToDo from Array value (token JsonToken.START_ARRAY) at [Source: (String)"[{"id":14,"text":"TEST","completed":true},{"id":13,"text":"TEST","completed":true},{"id":19,"text":"TEST","completed":true"[truncated 84 chars]; line: 1, column: 1]

WORK

private val mapper = ObjectMapper().registerKotlinModule() ..... val todos = mapper.readValue(response.body(), Array<ToDo>::class.java) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.