JSON в hashmap (Jackson)
Я хочу преобразовать JSON в хэш-карту с помощьюJackson . Это мой JSON:
String json = "[{"Opleidingen":[{"name":"Bijz. trajecten zorg en welzijn","afk":"BTZW","id":"0"},{"name":"Bouwkunde","afk":"Bwk","id":"14"},{"name":"Electrotechniek / mechatronica","afk":"EltMe","id":"15"},{"name":"Extern","afk":"Extern","id":"16"},{"name":"Gezondheidszorg","afk":"Zorg","id":"17"},{"name":"Handel","afk":"Hand","id":"18"},{"name":"Horeca","afk":"Hor","id":"19"},{"name":"Ict","afk":"ICT","id":"20"},{"name":"Maatschappelijke zorg","afk":"MZ","id":"21"},{"name":"Onderwijs assistent / pedagogisch werk","afk":"OAPW","id":"22"},{"name":"Tab / brug","afk":"TAB","id":"23"},{"name":"Werktuigbouw / maritieme techniek","afk":"WtbMt","id":"24"},{"name":"Zakelijke dienstverlening","afk":"TAB","id":"25"}]},{"Klassen":[{"name":"V2ZWA","cat":"BTZW","id":"1"},{"name":"V2ZWB","cat":"Bwk","id":"2"},{"name":"V2ZWB","cat":"BTZW","id":"3"},{"name":"V3B2A","cat":"BTZW","id":"3"},{"name":"V3B2B","cat":"BTZW","id":"4"},{"name":"V3B2C","cat":"BTZW","id":"5"},{"name":"V3B2D","cat":"BTZW","id":"6"},{"name":"V3B2E","cat":"BTZW","id":"7"},{"name":"V3B3A","cat":"BTZW","id":"8"},{"name":"V3B3B","cat":"BTZW","id":"9"},{"name":"V3B3C","cat":"BTZW","id":"10"},{"name":"VWA","cat":"BTZW","id":"11"},{"name":"VWB","cat":"BTZW","id":"12"},{"name":"VWC","cat":"BTZW","id":"13"}]}]";
Я хочу, чтобы я заполнил идентификатор, который я получаю обратно, поэтому: result.get("13"); возвращает VWC и result.get("0"); возвращает Bijz. trajecten zorg en welzijn.
Я пробовал это:
try {
@SuppressWarnings("unchecked")
ArrayList<LinkedHashMap<?, ?>> result = new ObjectMapper().readValue(json, ArrayList.class);
System.out.println(result.get(1).get("id"));
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Но тогда это и есть содержание
result.get(1);: I/System.out(809): {Klassen=[{name=V2ZWA, cat=BTZW, id=1}, {name=V2ZWB, cat=Bwk, id=2}, {name=V2ZWB, cat=BTZW, id=3}, {name=V3B2A, cat=BTZW, id=3}, {name=V3B2B, cat=BTZW, id=4}, {name=V3B2C, cat=BTZW, id=5}, {name=V3B2D, cat=BTZW, id=6}, {name=V3B2E, cat=BTZW, id=7}, {name=V3B3A, cat=BTZW, id=8}, {name=V3B3B, cat=BTZW, id=9}, {name=V3B3C, cat=BTZW, id=10}, {name=VWA, cat=BTZW, id=11}, {name=VWB, cat=BTZW, id=12}, {name=VWC, cat=BTZW, id=13}]}
Также я пробовал это без Джексона:
for (int i = 0; i < jObject.length(); i++) {
JSONArray opleidingen = jObject.getJSONObject(i).getJSONArray("Opleidingen");
for (int i2 = 0; i2 < opleidingen.length(); i2++) {
outMap.put(opleidingen.getJSONObject(i2).getString("id"), opleidingen.getJSONObject(i2).getString("name"));
}
JSONArray klassen = jObject.getJSONObject(i).getJSONArray("Klassen");
for (int i3 = 0; i3 < klassen.length(); i3++) {
outMap.put(klassen.getJSONObject(i3).getString("id"), klassen.getJSONObject(i3).getString("name"));
}
}
Но это ни то, ни другое не работает.
Можно ли преобразовать мой JSON в хэш-карту (и когда ID задан, что он возвращает имя)?
(класс ArrayList можно найти здесь )
2 ответов:
Я думаю, вам следует отделить логику десериализации от способа извлечения имен в конце. Для десериализации Используйте как можно более простой метод. Например, вы можете создать POJO классы, которые описывают ваш JSON. Смотрите пример ниже. Классы POJO:
Теперь вы можете легко десериализовать его следующим образом:class EntitiesOwner { private String name; private List<Entity> entities; @JsonAnySetter public void setProperties(String name, List<Entity> entities) { this.name = name; this.entities = entities; } public String getName() { return name; } public List<Entity> getEntities() { return entities; } @Override public String toString() { return "EntitiesOwner [name=" + name + ", entities=" + entities + "]"; } } class Entity { private int id; private String afk; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAfk() { return afk; } public void setAfk(String afk) { this.afk = afk; } public void setCat(String cat) { this.afk = cat; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Entity [id=" + id + ", afk=" + afk + ", name=" + name + "]"; } }ObjectMapper mapper = new ObjectMapper(); EntitiesOwner[] owners = mapper.readValue(json, EntitiesOwner[].class); System.out.println(Arrays.toString(owners));Выше программа печатает:
[EntitiesOwner [name=Opleidingen, entities=[Entity [id=0, afk=BTZW, name=Bijz. trajecten zorg en welzijn], Entity [id=14, afk=Bwk, name=Bouwkunde], Entity [id=15, afk=EltMe, name=Electrotechniek / mechatronica], Entity [id=16, afk=Extern, name=Extern], Entity [id=17, afk=Zorg, name=Gezondheidszorg], Entity [id=18, afk=Hand, name=Handel], Entity [id=19, afk=Hor, name=Horeca], Entity [id=20, afk=ICT, name=Ict], Entity [id=21, afk=MZ, name=Maatschappelijke zorg], Entity [id=22, afk=OAPW, name=Onderwijs assistent / pedagogisch werk], Entity [id=23, afk=TAB, name=Tab / brug], Entity [id=24, afk=WtbMt, name=Werktuigbouw / maritieme techniek], Entity [id=25, afk=TAB, name=Zakelijke dienstverlening]]], EntitiesOwner [name=Klassen, entities=[Entity [id=1, afk=BTZW, name=V2ZWA], Entity [id=2, afk=Bwk, name=V2ZWB], Entity [id=3, afk=BTZW, name=V2ZWB], Entity [id=3, afk=BTZW, name=V3B2A], Entity [id=4, afk=BTZW, name=V3B2B], Entity [id=5, afk=BTZW, name=V3B2C], Entity [id=6, afk=BTZW, name=V3B2D], Entity [id=7, afk=BTZW, name=V3B2E], Entity [id=8, afk=BTZW, name=V3B3A], Entity [id=9, afk=BTZW, name=V3B3B], Entity [id=10, afk=BTZW, name=V3B3C], Entity [id=11, afk=BTZW, name=VWA], Entity [id=12, afk=BTZW, name=VWB], Entity [id=13, afk=BTZW, name=VWC]]]]Для разрешения сущностей я предлагаю создать новый класс, который может помочь вам в этом. Для пример:
class EntityResolver { private Map<Integer, Entity> entities; public EntityResolver(EntitiesOwner[] owners) { entities = new HashMap<Integer, Entity>(owners.length); for (EntitiesOwner owner : owners) { for (Entity entity : owner.getEntities()) { entities.put(entity.getId(), entity); } } } public Entity getById(int id) { return entities.get(id); } }Простое использование:
EntityResolver resolver = new EntityResolver(owners); System.out.println(resolver.getById(0).getName()); System.out.println(resolver.getById(13).getName());Выше программа печатает:
Bijz. trajecten zorg en welzijn VWC
По умолчанию список в JSON сопоставляется с ArrayList в Java. Возможно, есть способ десериализовать список в хэш-карту напрямую, но даже тогда этот метод будет очень сложным. Почему бы просто не десериализовать список JSON в ArrayList и не выполнить некоторую постобработку для получения хэш-карты? Что-то вроде этого:
public Map<Integer, String> listToMap(List<Object> list) { Map<Integer, String> map = new HashMap<>(); for (Object obj : list) { // you might want to try-catch all casts, some data might be invalid Map<String, Object> elt = (Map<String, Object>) obj; Integer id = (Integer) elt.get("id"); String name = (String) elt.get("name"); map.put(id, name); } return map; }EDIT
Я не уточнил, как получить список для подачи в метод выше. В приведенном ниже фрагменте я использую строку
json, Как вы ее объявили в вашем вопросе. Для полноты информации обратитесь к привязке необработанных данных из документации Джексона .Теперь вы можете использовать эти две карты так, как вы описали:List<Object> inputData = new ObjectMapper().readValue(json, List.class); Map<String, Object> inputMap = (Map<String, Object>) inputData.get(0); List<Object> opleidingen = (List<Object>) inputMap.get("Opleidingen"); List<Object> klassen = (List<Object>) inputMap.get("Klassen"); Map<Integer, String> opleidingenMap = listToMap(opleidingen); Map<Integer, String> klassenMap = listToMap(klassen);opleidingenMap.get(25)Дает
Обратите внимание, что таким образом вы получите отдельную карту для оплейдингена и Классена. Если вы предпочитаете иметь все элементы в одной карте, вы можете сделать такую карту, как:"Zakelijke dienstverlening"Обратите внимание, что это предполагает, что не существует opleiding с тем же идентификатором, что и некоторые klas.Map<Integer, String> fullMap = new HashMap<>(); fullMap.putAll(opleidingenMap); fullMap.putAll(klassen);
Comments