2013-11-07 4 views
6

Я пытаюсь динамически разобрать некоторые JSON на карту. Следующее хорошо работает с простым JSONВложенные Json на карту с использованием Jackson

 String easyString = "{\"name\":\"mkyong\", \"age\":\"29\"}"; 
    Map<String,String> map = new HashMap<String,String>(); 
    ObjectMapper mapper = new ObjectMapper(); 

    map = mapper.readValue(easyString, 
      new TypeReference<HashMap<String,String>>(){}); 

    System.out.println(map); 

Но терпит неудачу, когда я пытаюсь использовать некоторые более сложные JSON с вложенной информацией. Я пытаюсь разобрать выборочные данные из json.org

{ 
    "glossary": { 
    "title": "example glossary", 
    "GlossDiv": { 
     "title": "S", 
     "GlossList": { 
     "GlossEntry": { 
      "ID": "SGML", 
      "SortAs": "SGML", 
      "GlossTerm": "Standard Generalized Markup Language", 
      "Acronym": "SGML", 
      "Abbrev": "ISO 8879:1986", 
      "GlossDef": { 
      "para": "A meta-markup language, used to create markup languages such as DocBook.", 
      "GlossSeeAlso": [ 
       "GML", 
       "XML" 
      ] 
      }, 
      "GlossSee": "markup" 
     } 
     } 
    } 
    } 
} 

Я получаю следующую ошибку

Исключения в потоке «основной» com.fasterxml.jackson.databind.JsonMappingException: Невозможно десериализация экземпляра java.lang.String из токена START_OBJECT

Есть ли способ разбора сложных данных JSON на карту?

+1

Вы хотите получить результат в простой карте ключа/значения? Как вы думаете, данные JSON будут представлены на такой карте? Какими будут ключи и ценности? –

+2

Я думаю, что ошибка связана с тем, что в минуту Джексон встречает символ {, он рассматривает оставшийся контент как новый объект, а не строку. Вы пробовали определить свою карту как HashMap ? – JamesB

+0

James no Я еще не пробовал. Cyrille, я пытаюсь разобрать JSON dynamiclly, не создавая объект со статической структурой. Приложение, над которым я работаю, получит JSON, я не буду знать, что схема впереди времени. В идеале, я хочу, чтобы у меня было какое-то сопоставление, в котором хранился JSON, поэтому я могу пройти через него сверху вниз, не зная об этом заранее, и пусть пользователь выбирает, какие данные они хотят вернуть. – user2229544

ответ

9

Я думаю, что ошибка возникает из-за того, что в минуту Джексон встречает символ {, он рассматривает оставшийся контент как новый объект, а не строку. Попробуйте Object в качестве значения карты вместо String.

public static void main(String[] args) throws IOException { 

    Map<String,String> map = new HashMap<String,String>(); 
    ObjectMapper mapper = new ObjectMapper(); 

    map = mapper.readValue(x, new TypeReference<HashMap>(){}); 

    System.out.println(map); 
} 

выход

{glossary={title=example glossary, GlossDiv={title=S, GlossList={GlossEntry={ID=SGML, SortAs=SGML, GlossTerm=Standard Generalized Markup Language, Acronym=SGML, Abbrev=ISO 8879:1986, GlossDef={para=A meta-markup language, used to create markup languages such as DocBook., GlossSeeAlso=[GML, XML]}, GlossSee=markup}}}}} 
+0

Отлично! Именно то, что я искал :) – Marchev

1

Оберните карту в немой объект как контейнер, например:

public class Country { 
    private final Map<String,Map<String,Set<String>>> citiesAndCounties=new HashMap<>; 

    // Generate getters and setters and see the magic happen. 
} 

Остальное просто работает с картографа объектов, например, объектов картографа с использованием Joda модуль:

public static final ObjectMapper JSON_MAPPER=new ObjectMapper(). 
      disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES). 
      setSerializationInclusion(JsonInclude.Include.NON_NULL). 
      disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS). 
      registerModule(new JodaModule()); 

// Calling your Object mapper 
JSON_MAPPER.writeValueAsString(new Country()); 

Надеюсь, что помогает ;-)

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