【问题标题】:Jackson mapping to POJO cannot deserialize instance instance杰克逊映射到 POJO 无法反序列化实例实例
【发布时间】:2013-10-18 10:58:46
【问题描述】:

我正在接收杰克逊格式的数据,并希望将其读入我定义的 POJO。我要么错误地定义了 POJO,要么错过了一些关键步骤。接收到的数据格式如下:

{
    streetSegment: [
    {
        distance: "0.04",
        highway: "residential",
        name: "Swift",
        line: "-1.6720224 52.6251985,-1.6721061 52.6250432,-1.6721799,             52.6248908,-1.6721996 52.6247594",
        wayId: "76473524"
    },
    {
        distance: "0.05",
        highway: "residential",
        name: "Swift",
        line: "-1.6721799 52.6248908,-1.6723374 52.6248669,-1.6732035 52.6249774,-1.6734643 52.6249894",
        wayId: "76473523"
    }
    ]
}

我已将 POJO 定义为:

public class StreetSegment {

public static class Street {
    private String distance;
    private String highway;
    private String name;
    private String line;
    private String wayId;
    public Street() {
        super();
    }
    public String getDistance() {
        return distance;
    }
    public void setDistance(String distance) {
        this.distance = distance;
    }
    public String getHighway() {
        return highway;
    }
    public void setHighway(String highway) {
        this.highway = highway;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLine() {
        return line;
    }
    public void setLine(String line) {
        this.line = line;
    }
    public String getWayId() {
        return wayId;
    }
    public void setWayId(String wayId) {
        this.wayId = wayId;
    }
}

}

当我使用以下行读取对象映射器时:

List<StreetSegment> list = mObjectMapper.readValue( in, new TypeReference<List<StreetSegment>>(){} );

我得到一个异常,如图所示:

10-18 12:49:57.596: W/System.err(31776): com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
10-18 12:49:57.596: W/System.err(31776):  at [Source: java.io.StringReader@42ea8038; line: 1, column: 1]
10-18 12:49:57.606: W/System.err(31776):    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:575)
10-18 12:49:57.616: W/System.err(31776):    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:569)
10-18 12:49:57.616: W/System.err(31776):    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:259)
10-18 12:49:57.626: W/System.err(31776):    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
10-18 12:49:57.626: W/System.err(31776):    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:207)
10-18 12:49:57.636: W/System.err(31776):    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
10-18 12:49:57.636: W/System.err(31776):    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
10-18 12:49:57.646: W/System.err(31776):    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2041)
10-18 12:49:57.646: W/System.err(31776):    at co.uk.dominion.test.MainActivity$19._getStreetSegmentFromURL(MainActivity.java:3428)
10-18 12:49:57.646: W/System.err(31776):    at co.uk.dominion.test.MainActivity$19.doInBackground(MainActivity.java:3460)
10-18 12:49:57.656: W/System.err(31776):    at co.uk.dominion.test.MainActivity$19.doInBackground(MainActivity.java:1)
10-18 12:49:57.656: W/System.err(31776):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-18 12:49:57.656: W/System.err(31776):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
10-18 12:49:57.656: W/System.err(31776):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-18 12:49:57.656: W/System.err(31776):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-18 12:49:57.656: W/System.err(31776):    at java.lang.Thread.run(Thread.java:856)

我还尝试先定义为 JsonNode,看看是否能发现问题,但无济于事:

JsonNode node = mObjectReader.readValue(in);
List<StreetSegment> list = mObjectMapper.readValue(node.toString(), new TypeReference<List<StreetSegment>>(){});

【问题讨论】:

    标签: java android json jackson pojo


    【解决方案1】:

    通过这种方式创建Street

    街道

    public class Street {
        private List<StreetSegment> streetSegment;
    
        public Street() {
            // TODO Auto-generated constructor stub
        }
    
        public List<StreetSegment> getStreetSegment() {
            return streetSegment;
        }
    
        public void setStreetSegment(List<StreetSegment> streetSegment) {
            this.streetSegment = streetSegment;
        }
    }
    

    街景

    public class StreetSegment {
        private String distance;
        private String highway;
        private String name;
        private String line;
        private String wayId;
    
        public StreetSegment() {
    
        }
        public String getDistance() {
            return distance;
        }
        public void setDistance(String distance) {
            this.distance = distance;
        }
        public String getHighway() {
            return highway;
        }
        public void setHighway(String highway) {
            this.highway = highway;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getLine() {
            return line;
        }
        public void setLine(String line) {
            this.line = line;
        }
        public String getWayId() {
            return wayId;
        }
        public void setWayId(String wayId) {
            this.wayId = wayId;
        }
    }
    

    要检查它,这里是main

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
            String str = "{" + 
                    "    \"streetSegment\": [" + 
                    "        {" + 
                    "            \"distance\": \"0.04\"," + 
                    "            \"highway\": \"residential\"," + 
                    "            \"name\": \"Swift\"," + 
                    "            \"line\": \"-1.6720224 52.6251985,-1.6721061 52.6250432,-1.6721799,             52.6248908,-1.6721996 52.6247594\"," + 
                    "            \"wayId\": \"76473524\"" + 
                    "        }," + 
                    "        {" + 
                    "            \"distance\": \"0.05\"," + 
                    "            \"highway\": \"residential\"," + 
                    "            \"name\": \"Swift\"," + 
                    "            \"line\": \"-1.6721799 52.6248908,-1.6723374 52.6248669,-1.6732035 52.6249774,-1.6734643 52.6249894\"," + 
                    "            \"wayId\": \"76473523\"" + 
                    "        }" + 
                    "    ]" + 
                    "}";
        // to simulate stream reader    
        InputStreamReader in = new InputStreamReader(new ByteArrayInputStream(str.getBytes())); 
    
         BufferedReader streamReader = new BufferedReader(in); 
    
        StringBuilder buff = new StringBuilder();
    
        String inputStr;
        while ((inputStr = streamReader.readLine()) != null)
            buff.append(inputStr);
    
    
        ObjectMapper mapper = new ObjectMapper();
    
        Street mj = mapper.readValue(buff.toString(), Street.class);
    
            if(mj == null){
                System.err.println("null");
            }                
        }
    

    检查中...

    System.out.println(mj.getStreetSegment().get(0).getHighway());//dummy print
    

    输出:residential

    【讨论】:

    • 感谢您的快速回复。奇怪的是,您的代码可以正常工作,但是当它与 JsonNode 和 node.toString() 一起使用时却不能。我已经并排比较了字符串,它们看起来是一样的。
    • 在我的情况下,StreetSegment 不是 Street 的孩子。我不使用super()
    • 我把它拿出来以符合您对 StreetSegment 的定义。刚刚注意到我现在在堆栈跟踪中看到这个,我不知道 ref 是什么...... UnrecognizedPropertyException:无法识别的字段“ref”(类 co.uk.dominion.test.StreetSegment),未标记为可忽略(5 个已知属性: , "line", "distance", "wayId", "name", "highway"])
    • 查看我的编辑,我将字符串转换为字节并使用InputStreamReader
    • 啊啊啊!我刚刚意识到有时返回的数据中还有一个 Ref 字段 - 多么愚蠢的疏忽!非常感谢您的帮助,POJO 现在是正确的!
    【解决方案2】:

    在两个单独的类中重新定义您的模型,即 StreetSegmentStreet

    public class StreetSegment {
        list<Street> street_list;
    
        //getters and setters
    }
    

    public class Street {
         private String distance;
         private String highway;
         private String name;
         private String line;
         private String wayId;
    
          //getters and setters
     }
    

    //如果你的问题解决了就跳过其他的

    我猜您正在使用 @RequestBody 来获取 JSON 请求正文。 我会这样使用它:

    public your_return_type your_method(@RequestBody String rb) {
        ObjectMapper om = new ObjectMapper();
        StreetSegment ss = om.readValue(rb, StreetSegment.class);
    
        //and the rest
        .
        .
        .
    

    【讨论】:

    • 感谢您的快速回复。抱歉,不确定@RequestBody 是什么意思 - 我正在使用 InputStreamReader in = new InputStreamReader(conn.getInputStream()) 读取 JSON,然后在对象映射器中处理 InputStreamReader。我尝试了您和 Maxim 提出的更改,但遇到了同样的问题。
    • 感谢您的帮助,Maxims 和您的帮助都整理好了!
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 2012-11-19
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 2019-06-20
    相关资源
    最近更新 更多