简体   繁体   中英

Parsing a JSONArray object, containing JSON arrays, to a list of JSON arrays

I am using a PrimeFaces JSONArray object containing JSON arrays, eg (simplified)

[['james', 12, 2019], ['sarah', 29, 2015], ['robert', 15, 2011]]

as input to a static build method which runs over the fields of the nested arrays to construct a POJO representing their data. I implement this using static build methods within both the entity and container-of-entity classes (the latter of which simply parses the JSON and calls the former build method to construct each entity). This works fine with a crude for loop:

public static MyContainer buildContainer(JSONArray json) {
    MyContainer list = new MyContainer ();
    for (int i = 0; i < json.length(); i++) {
        MyEntity ent = MyEntity.buildEntity(json, i);
        list.add(ent);
    }
    return list;
}

but I would like a more elegant solution, in particular one using a functional approach (to improve my knowledge of functional Java, if for no better reason). I use Jackson to parse the JSONArray representing my complete dataset to an array of JSONArrays ( ie a JSONArray[] ). This array can then be converted to a list, which allows easier functional manipulation. Here is my initial attempt at writing down what I think that would look like, which probably shows some fundamental misunderstandings of Jackson and functional Java:

public static MyContainer buildContainer(JSONArray json) {
    ObjectMapper mapper = new ObjectMapper();
    try {
        JSONArray[] jaArr = mapper.readValue(json.toString(), JSONArray[].class);
        List<JSONArray> jaList = Arrays.asList(jaArr);
        MyContainer list = (MyContainer) (List<MyEntity>) Arrays.asList(json)
                .stream()
                .map(MyEntity::buildEntity)
                .collect(Collectors.toList());
        return list;
    } catch (JsonProcessingException ex) {
        return null;
    }
}

Netbeans does not suggest anything is wrong with this, and there are no compile-time issues. At runtime, however, I get the exception

Severe: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.primefaces.json.JSONArray out of START_ARRAY token.

So, my questions are why this exception arises, when the input is of the format I have shown above, and whether there is a more elegant solution than serialising the JSONArray to a string then reading it back as a JSONArray[] – ie could I convert my initial JSONArray more directly to a type that allows .stream() or .forEach() ?

JSONArray in version 7.0 implements Iterable so you can do something like this:

StreamSupport
  .stream(iterable.spliterator(), false)
  .map(MyEntity::buildEntity)
  .collect(Collectors.toList());

See also:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM