【问题标题】:Parsing an array of JSON objects using Jackson 2.0使用 Jackson 2.0 解析 JSON 对象数组
【发布时间】:2013-07-05 19:05:32
【问题描述】:

我正在将 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 的 1.9.4 的 ObjectMapper 头文件包含这些 JsonNodes 的 readValue 方法:

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

【问题讨论】:

    标签: android json jackson


    【解决方案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

    【讨论】:

    • 如果类 Foo 有自定义反序列化器则不起作用
    • 或者,您可以使用ObjectMapper.treeToValue() 调用,旨在为所欲为。
    【解决方案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;
    }
    

    【讨论】:

    • 什么是 getRootName()?以及如何使其通用以处理任何 RootName??
    猜你喜欢
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多