使用 Jackson 和消息解析 JSON 文件中的内容时出现问题 - JsonMappingException - 无法反序列化为超出 START_ARRAY 令牌
Posted
技术标签:
【中文标题】使用 Jackson 和消息解析 JSON 文件中的内容时出现问题 - JsonMappingException - 无法反序列化为超出 START_ARRAY 令牌【英文标题】:Issue with parsing the content from JSON file with Jackson & message- JsonMappingException -Cannot deserialize as out of START_ARRAY token 【发布时间】:2013-10-20 10:00:48 【问题描述】:给定以下 .json 文件:
[
"name" : "New York",
"number" : "732921",
"center" : [
"latitude" : 38.895111,
"longitude" : -77.036667
]
,
"name" : "San Francisco",
"number" : "298732",
"center" : [
"latitude" : 37.783333,
"longitude" : -122.416667
]
]
我准备了两个类来表示包含的数据:
public class Location
public String name;
public int number;
public GeoPoint center;
...
public class GeoPoint
public double latitude;
public double longitude;
为了解析 .json 文件中的内容,我使用了Jackson 2.2.x 并准备了以下方法:
public static List<Location> getLocations(InputStream inputStream)
ObjectMapper objectMapper = new ObjectMapper();
try
TypeFactory typeFactory = objectMapper.getTypeFactory();
CollectionType collectionType = typeFactory.constructCollectionType(
List.class, Location.class);
return objectMapper.readValue(inputStream, collectionType);
catch (IOException e)
e.printStackTrace();
return null;
只要我省略了center
属性,所有内容都可以被解析。但是,当我尝试解析地理坐标时,我最终会收到以下错误消息:
com.fasterxml.jackson.databind.JsonMappingException:无法反序列化的实例 com.example.GeoPoint 在 [Source: android.content.res.AssetManager$AssetInputStream@416a5850;行:5,列:25] (通过引用链:com.example.Location["center"])
【问题讨论】:
如果可以简单地用json解析器解析,为什么还要使用jackson 您的 JSON 字符串格式错误,center
的类型是无效对象数组。尝试将 longitude
和 latitude
周围 JSON 字符串中的
和
替换为 [
和 ]
,这样它们就会成为对象。
@Katona 谢谢。您能否将您的评论转换为答案,以便我关闭问题?!
我遇到了同样的错误,但因为我使用了 LocalDate 类。一旦我用“mapper.registerModule(new JavaTimeModule());”添加了缺失的 JavaTimeModule ,问题就解决了。
【参考方案1】:
JsonMappingException: out of START_ARRAY token
异常由 Jackson 对象映射器抛出,因为它期待 Object
,而它找到了 Array []
作为响应。
这可以通过在geForObject("url",Object[].class)
的参数中将Object
替换为Object[]
来解决。
参考资料:
-
Ref.1
Ref.2
Ref.3
【讨论】:
【参考方案2】:您的 JSON 字符串格式错误:center
的类型是无效对象数组。将longitude
和latitude
周围的JSON 字符串中的[
和]
替换为 和
,这样它们就会成为对象:
[
"name" : "New York",
"number" : "732921",
"center" :
"latitude" : 38.895111,
"longitude" : -77.036667
,
"name" : "San Francisco",
"number" : "298732",
"center" :
"latitude" : 37.783333,
"longitude" : -122.416667
]
【讨论】:
我遇到了同样的问题,但它很疯狂,因为在 jackson 2.6.3v 中有一个完全不同的疯狂错误,并且在 2.9.8v 中一切正常。该死,所以这些序列化错误太烦人了。 Atul Sharma answer 下面看起来与这个问题更相关。请检查和修改。谢谢【参考方案3】:我将此问题分类为验证来自 JSONLint.com 的 json,然后更正它。这是相同的代码。
String jsonStr = "[\r\n" + "\"name\":\"New York\",\r\n" + "\"number\": \"732921\",\r\n"+ "\"center\": \r\n" + "\"latitude\": 38.895111,\r\n" + " \"longitude\": -77.036667\r\n" + "\r\n" + ",\r\n" + " \r\n"+ "\"name\": \"San Francisco\",\r\n" +\"number\":\"298732\",\r\n"+ "\"center\": \r\n" + " \"latitude\": 37.783333,\r\n"+ "\"longitude\": -122.416667\r\n" + "\r\n" + "\r\n" + "]";
ObjectMapper mapper = new ObjectMapper();
MyPojo[] jsonObj = mapper.readValue(jsonStr, MyPojo[].class);
for (MyPojo itr : jsonObj)
System.out.println("Val of name is: " + itr.getName());
System.out.println("Val of number is: " + itr.getNumber());
System.out.println("Val of latitude is: " +
itr.getCenter().getLatitude());
System.out.println("Val of longitude is: " +
itr.getCenter().getLongitude() + "\n");
注意:MyPojo[].class
是具有 json 属性的 getter 和 setter 的类。
结果:
Val of name is: New York
Val of number is: 732921
Val of latitude is: 38.895111
Val of longitude is: -77.036667
Val of name is: San Francisco
Val of number is: 298732
Val of latitude is: 37.783333
Val of longitude is: -122.416667
【讨论】:
这解决了我几天来一直遇到的问题,没有其他答案有意义。对于其他有同样错误的人。值得注意的是,如果您的 JSON 中有多个对象,则需要返回多个对象。我一直在返回 MyObject,我应该返回 MyObject[]【参考方案4】:如前所述,Jackson 对象映射器抛出 JsonMappingException: out of START_ARRAY token
异常,因为它期待 Object
,而它发现 Array []
作为响应。
更简单的解决方案可能是将方法 getLocations
替换为:
public static List<Location> getLocations(InputStream inputStream)
ObjectMapper objectMapper = new ObjectMapper();
try
TypeReference<List<Location>> typeReference = new TypeReference<>() ;
return objectMapper.readValue(inputStream, typeReference);
catch (IOException e)
e.printStackTrace();
return null;
另一方面,如果你没有像 Location
这样的 pojo,你可以使用:
TypeReference<List<Map<String, Object>>> typeReference = new TypeReference<>() ;
return objectMapper.readValue(inputStream, typeReference);
【讨论】:
感谢您分享这个替代实现。您能说出使用CollectionType
和TypeReference
的优缺点吗?
TypeReference
语法比其他语法短得多。不确定,如果在某些情况下可能有与类型擦除相关的反指示......但在我的世界里,TypeReference
更容易使用和理解。以上是关于使用 Jackson 和消息解析 JSON 文件中的内容时出现问题 - JsonMappingException - 无法反序列化为超出 START_ARRAY 令牌的主要内容,如果未能解决你的问题,请参考以下文章