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

Answer #1 100 %

The problem is the JSON - this cannot, by default, be deserialized into a Collection because it's not actually a JSON Array - that would look like this:

        "name": "Test order1",
        "detail": "ahk ks"
        "name": "Test order2",
        "detail": "Fisteku"

Since you're not controlling the exact process of deserialization (RestEasy does) - a first option would be to simply inject the JSON as a String and then take control of the deserialization process:

Collection readValues = new ObjectMapper().readValue(
    jsonAsString, new TypeReference>() { }

You would loose a bit of the convenience of not having to do that yourself, but you would easily sort out the problem.

Another option - if you cannot change the JSON - would be to construct a wrapper to fit the structure of your JSON input - and use that instead of Collection.

Hope this helps.

Answer #2 100 %

Instead of the JSON document, you can update the ObjectMapper object like below :

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
Answer #3 100 %

This will work:

The problem may happen when you're trying to read a list with a single element as a JsonArray rather than a JsonNode or vice versa.

Since you can't know for sure if the returned list contains a single element (so the json looks like this {...}) or multiple elements (and the json looks like this [{...},{...}]) - you'll have to check in runtime the type of the element.

It should look like this:

(Note: in this code sample I'm using com.fasterxml.jackson)

String jsonStr = response.readEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(jsonStr);

// Start by checking if this is a list -> the order is important here:                      
if (rootNode instanceof ArrayNode) {
    // Read the json as a list:
    myObjClass[] objects = mapper.readValue(rootNode.toString(), myObjClass[].class);
} else if (rootNode instanceof JsonNode) {
    // Read the json as a single object:
    myObjClass object = mapper.readValue(rootNode.toString(), myObjClass.class);
} else {
Answer #4 100 %

Related to Eugen's answer, you can solve this particular case by creating a wrapper POJO object that contains a Collection as its member variable. This will properly guide Jackson to place the actual Collection data inside the POJO's member variable and produce the JSON you are looking for in the API request.


public class ApiRequest {

   private Collection collection;

   // getters

Then set the parameter type of COrderRestService.postOrder() to be your new ApiRequest wrapper POJO instead of Collection.

You’ll also like:

© 2023 CodeForDev.com -