使用FlexJSON </string,>将JSON解析为Map <string,entity =“”>

时间:2010-11-02 13:55:35

标签: java deserialization json flexjson

我正在尝试解析类似于这个的JSON结构:

    {
 "cars": {
  "112": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "1998"
  },
  "642": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "1990"
  },
  "9242": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "2001"
  }
 }}

我有一个CarEntity类,定义了makeName,model,year属性,通过setter / getters定义和访问。

我试图像这样反序列化这个JSON:

    Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String, CarEntity>>()
   .use("cars.values", Map.class)
   .deserialize(json);

并且它不起作用:(它确实反序列化了它,但没有反映到Map<String, CarEntity>中,而是深入地图(类似于Map<String, Map<String, Map<String, String>>>

我做错了什么?

3 个答案:

答案 0 :(得分:2)

你的问题是你的json有两张地图。一个包含'cars'键,另一个包含实际的CarEntity。不幸的是,您不能在Map中引用单个键,并且此时只能在该键上分配类型。通常,集合值的设置类型是指集合中的所有值。您不需要为包含“cars”键的第一个Map指定类型,因为它会默认反序列化它。

Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String,Map<String, CarEntity>>>()
    .use("values.values", CarEntity.class )
    .deserialize(json).get("cars");

路径'values.values'是指外部Map的值,然后遍历下一个map值是所有CarEntity实例。

我考虑过将路径表达式更改为更具表现力,允许您在集合中定位单个值,但这会增加评估它们的开销并向后兼容是一项挑战。

答案 1 :(得分:1)

你最有可能被Java Type Erasure咬伤:有问题的JSON库不知道你想要的类型;它看到的只相当于Map。所以你必须以某种方式至少指定值类型。希望FlexJSON文档指出如何。

或者你可以将HashMap子类化为你自己的类型(MyEntityMap扩展HashMap),因为那时类型信息可以从泛型超类型中推断出来;并且传递MyEntityMap.class将提供大多数JSON库可以使用的类型信息(至少Jackson和GSON)。

如果这些不起作用,Jackson和GSON库可以轻松处理这个用例;两者都有方法来指定反序列化的泛型类型。

答案 2 :(得分:0)

只需再添加一个get("cars")的电话,例如:

Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String, CarEntity>>()
   .use("cars.values", Map.class)
   .deserialize(json).get("cars");

jSon字符串可能是从cars

类型的变量Map<String, CarEntity>序列化的