Разбор массива объектов JSON с использованием Jackson 2.0

Я занимаюсь модернизацией Jackson с 1.9.4 до 2.2.0. Переход был плавным, за исключением того, что я не могу получить парсинг массива для работы с объектами. В 1.9.4 я мог бы сделать это:

private List<Subjects> mSubjects;
mSubjects = objectMapper.readValue(subjectsJsonArrayNode, new TypeReference<List<Subjects>>() {});

С Jackson 2.2.0 я получаю ошибку компиляции "не могу разрешить метод". Файл заголовка Jackson ObjectMapper для 1.9.4 содержит эти методы readValue для JsonNodes:

public <T> T readValue(JsonNode root, java.lang.Class<T> valueType)
public <T> T readValue(JsonNode root, org.codehaus.jackson.type.TypeReference valueTypeRef)
public <T> T readValue(JsonNode root, org.codehaus.jackson.type.JavaType valueType)

И файл заголовка Jackson 2.2.0:

public <T> T readValue(JsonParser jsonParser, java.lang.Class<T> tClass)
public <T> T readValue(JsonParser jsonParser, com.fasterxml.jackson.core.type.TypeReference<?> typeReference)
public final <T> T readValue(JsonParser jsonParser, com.fasterxml.jackson.core.type.ResolvedType resolvedType)
public <T> T readValue(JsonParser jsonParser, com.fasterxml.jackson.databind.JavaType javaType) 

Поэтому мне нужно переключиться с передачи JsonNode на JsonParser, но я не совсем уверен, как сделать этот переход. Тем не менее, я не уверен, что я даже иду по правильному пути, потому что JsonParser определяется как абстрактный класс, поэтому я не могу даже легко инициализировать экземпляр, чтобы поиграть с ним.

Для тех, кто приходит без ответа, вот временное решение, которое у меня есть, где я повторяю и вручную разбираю каждый объект:

 private List<Subjects> mSubjects = new ArrayList<Subjects>();
 for(JsonNode subjectJsonNode : subjectsJsonArrayNode) {
    mSubjects.add(objectMapper.treeToValue(subjectJsonNode, Subject.class));
 }

Ответ 1

Вы можете просто вызвать метод JsonNode.traverse(), чтобы получить JsonParser.

Протестировано следующим простым примером:

public class App {

    public static class Foo {
        public int foo;
    }

    public static void main(String[] args) {

        String json = "{\"someArray\":[{\"foo\":5},{\"foo\":6},{\"foo\":7}]}";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode node = mapper.readTree(json);
        node = node.get("someArray");
        TypeReference<List<Foo>> typeRef = new TypeReference<List<Foo>>(){};
        List<Foo> list = mapper.readValue(node.traverse(), typeRef);
        for (Foo f : list) {
            System.out.println(f.foo);
        }
    }
}

выходы:

5
6
7

Ответ 2

Я использую этот метод для списков:

/**
 * Returns a list collection of any specified type
 * @param jsonValue the json string content to deserialize
 * @param type the type to serialize into
 * @return a list of specified type
 */
public List<?> readJSONToList(String jsonValue,Class<?> type){

    List<?> objDTOS=null;
    try {
        //get json content without root name
        JsonNode root= objectMapper.readTree(jsonValue).get(getRootName());
        TypeFactory tf = objectMapper.getTypeFactory();
        JavaType listOfObjs = tf.constructCollectionType(ArrayList.class,type);
        objDTOS=objectMapper.readValue(root.traverse(), listOfObjs);

    } catch (NullPointerException e) {
        Logger.write("Jackson Json List Reader", e.getMessage(), Logger.ERROR);
    } catch (JsonParseException e) {    
        Logger.write("Jackson Json List Reader", e.getMessage(), Logger.ERROR);
    } catch (IOException e) {
        Logger.write("Jackson Json List Reader", e.getMessage(), Logger.ERROR);
    }
    return  objDTOS;
}