2014-01-29 3 views
0

У меня есть следующие JSON:Джексона десериализации хэш-карта

"propertyName": "{"1":[{"1":"value1","2":"value2","3":false}]}" 

первое свойство является подсчет элементов в массиве следующих имеющий карту свойств.

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

class MyHolder 
{ 
    name = "value1"; 
    age = "value2"; 
    female = false; 
} 

, например.

+0

«Лучший» в каком смысле? –

+0

Возможный дубликат [Джексон: десериализация карты] (http://stackoverflow.com/questions/8362913/jackson-deserialization-of-map) –

ответ

4

Ваш JSON недействителен. Пусть Предположим, что JSON выглядит следующим образом:

{ 
    "propertyName":{ 
     "1":[ 
     { 
      "1":"value1", 
      "2":"value2", 
      "3":false 
     } 
     ] 
    } 
} 

Самый простой способ для создания классов POJO, которые подходят к вашему JSON. Например:

class Root { 

    private Map<String, List<MyHolder>> propertyName; 

    //getters,setters,toString 
} 

class MyHolder { 

    @JsonProperty("1") 
    private String name; 
    @JsonProperty("2") 
    private String age; 
    @JsonProperty("3") 
    private boolean female; 

    //getters,setters,toString 
} 

Теперь мы можем легко десериализации его таким образом:

ObjectMapper mapper = new ObjectMapper(); 
System.out.println(mapper.readValue("{.. json ...}", Root.class)); 

Над программа печатает:

Root [propertyName={1=[MyHolder [name=value1, age=value2, female=false]]}] 

Если мы не хотим, чтобы увидеть Map в нашем классе POJO мы должны написать собственный конвертер:

class MapMyHolderConverter implements Converter<Map<String, List<Map<String, Object>>>, List<MyHolder>> { 

    @Override 
    public JavaType getInputType(TypeFactory typeFactory) { 
     return typeFactory.constructMapType(Map.class, String.class, List.class); 
    } 

    @Override 
    public JavaType getOutputType(TypeFactory typeFactory) { 
     return typeFactory.constructCollectionType(List.class, MyHolder.class); 
    } 

    @Override 
    public List<MyHolder> convert(Map<String, List<Map<String, Object>>> map) { 
     Collection<List<Map<String, Object>>> values = map.values(); 
     if (values.isEmpty()) { 
      return Collections.emptyList(); 
     } 

     List<MyHolder> result = new ArrayList<>(); 
     for (Map<String, Object> item : values.iterator().next()) { 
      MyHolder holder = new MyHolder(); 
      holder.setName(item.get("1").toString()); 
      holder.setAge(item.get("2").toString()); 
      holder.setFemale((Boolean) item.get("3")); 
      result.add(holder); 
     } 

     return result; 
    } 
} 

Ваши классы POJO может выглядеть это сейчас:

class Root { 

    @JsonDeserialize(converter = MapMyHolderConverter.class) 
    private List<MyHolder> propertyName; 

    //getters,setters,toString 
} 

class MyHolder { 

    private String name; 
    private String age; 
    private boolean female; 

    //getters,setters,toString 
} 

Как вы можете видеть, во втором примере мы используем @JsonDeserialize аннотацию, и мы не использовать @JsonProperty.

6

Для десериализации в список/сбор конкретных значений (а затем LinkedHashMap вы получаете по умолчанию), вы должны передать информацию типа Джексона:

mapper.readValue(jsonString, new TypeReference<List<MyHolder>>() { }); 

Другой способ сделать то же самое:

CollectionType javaType = mapper.getTypeFactory().constructCollectionType(List.class, MyHolder.class); 
List<MyDto> asList = mapper.readValue(jsonString, javaType); 

Надеюсь, что это поможет.

+0

Это отлично работает. Например, для десериализации на карту : 'Карта myMap = mapper.readValue (json, new TypeReference >() {})' – razvang

Смежные вопросы