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 можно найти здесь )

543   2  

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"
Обратите внимание, что таким образом вы получите отдельную карту для оплейдингена и Классена. Если вы предпочитаете иметь все элементы в одной карте, вы можете сделать такую карту, как:
Map<Integer, String> fullMap = new HashMap<>();
fullMap.putAll(opleidingenMap);
fullMap.putAll(klassen);
Обратите внимание, что это предполагает, что не существует opleiding с тем же идентификатором, что и некоторые klas.

Comments

    Ничего не найдено.