【问题标题】:How to iterate through JSONArray which has JSONArray and JSONObject inside Java 8如何遍历在 Java 8 中具有 JSONArray 和 JSONObject 的 JSONArray
【发布时间】:2019-04-09 12:44:51
【问题描述】:

谁能告诉我如何遍历JSONArray,它会同时返回JSONArrayJSONObject。 我尝试了下面的代码,但出现如下错误。

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

代码

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"
  }
  }]
]

正常的for循环。

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 );
  }

我该如何使用Java 8

【问题讨论】:

标签: arrays json java-8 jackson objectmapper


【解决方案1】:

如果您使用JacksonObjectMapper,请尝试使用ACCEPT_SINGLE_VALUE_AS_ARRAY 功能,该功能允许将单个元素视为one-element-array。下面,您可以找到简单的示例,如何将您的 JSON 读取到 Pojo 类列表:

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
}

上面的代码打印:

[Pojo{key1='Value1'}, Pojo{key1='Value1-1'}]

【讨论】:

  • 我仍然收到错误com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String` out of START_ARRAY token`
  • 它在List&lt;List&lt;Pojo&gt;&gt; list = mapper.readValue(jsonFile, collectionType1); 中失败了
  • @Sam,我已经针对您在问题中包含的JSON 有效负载对其进行了测试。你测试过同样的JSON吗?
  • 是的,它的有效载荷相同。它的类型为JSONArray。当它返回JSONObject 时它工作正常,但是第二个值是JSONArray
  • @Sam,您使用哪个版本的Jackson?我已经测试了它的最新版本。
猜你喜欢
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 2011-10-05
相关资源
最近更新 更多