0

Could anyone tell me how to iterate through JSONArray which returns both JSONArray and JSONObject in it. I tried below code and I'm getting error as below.

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of 'com.example.jsonarr.pojoClass[]' out of START_OBJECT token

Code

List<pojoClass> pojoClassList = new ArrayList();
JSONArray jsonArrayList = new JSONArray( jsonResponse );
ObjectMapper objectMapper = new ObjectMapper(  );
pojoClassList = (List)objectMapper.readValue(jsonArrayList.toString(),
                        objectMapper.getTypeFactory().constructCollectionType(List.class, pojoClass[].class));

JSONArray

[
  {
  "Key1": "Value1",
  "Key2": "Value2",
  "Key3": "Value3",
  "Value1_tim":       {
     "amVal": 0,
     "pmVal": "0"
    }
  },
  [   {
  "Key1": "Value1",
  "Key2": "Value2",
  "Key3": "Value3",
  "Value1_tim":       {
     "amVal": 0,
     "pmVal": "0"
  }
  }]
]

With normal for loop.

for ( int i = 0; i < jsonArrayList.length(); i++ ) {
     JSONObject jsonObject = jsonArrayList.optJSONObject( i );
     if ( jsonObject != null ) {
        pojoClass = objectMapper.readValue( jsonObject.toString(), PojoClass.class );
           }
     if ( jsonObject == null ) {
        JSONArray jsonArrayInner = new JSONArray( jsonArrayList.getJSONArray( i ).toString() );
        for ( int j = 0; j < jsonArrayInner.length(); j++ ) {
         JSONObject jsonObject1 = jsonArrayList.optJSONObject( j );
           if ( jsonObject1 != null ) {
            pojoClass = objectMapper.readValue( jsonObject1.toString(), PojoClass.class );
                 }
             }
         }
    pojoClassList.add( pojoClass );
  }

How do I do that with Java 8?

1

1 Answer 1

0

If you use Jackson's ObjectMapper try to use ACCEPT_SINGLE_VALUE_AS_ARRAY feature which allows to treat single elements as one-element-array. Below, you can find simple example how to read your JSON to list of Pojo classes:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

        CollectionType collectionType0 = mapper.getTypeFactory().constructCollectionType(List.class, Pojo.class);
        CollectionType collectionType1 = mapper.getTypeFactory().constructCollectionType(List.class, collectionType0);
        List<List<Pojo>> list = mapper.readValue(jsonFile, collectionType1);

        List<Pojo> pojos = list.stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
        System.out.println(pojos);
    }
}

class Pojo {

    @JsonProperty("Key1")
    private String key1;

    // getters, setters, toString
}

Above code prints:

[Pojo{key1='Value1'}, Pojo{key1='Value1-1'}]
Sign up to request clarification or add additional context in comments.

7 Comments

I'm still getting an error com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String` out of START_ARRAY token`
It's failing in line List<List<Pojo>> list = mapper.readValue(jsonFile, collectionType1);
@Sam, I have tested it for JSON payload you included to a question. Have you tested it for the same JSON?
Yes, its the same payload. It's of type JSONArray. It's working fine when it returns JSONObject, however the second value is of JSONArray.
@Sam, which version of Jackson do you use? I've tested it for the latest one.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.