Java Parse Json-объект, содержащий отображение строк для отображения в строки в массив строк - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь разобрать строку json, которая является объектом, содержащим карту строковых ключей и карту строковых ключей в строковый массив.Я упростил строку json только до объекта, который я пытаюсь разобрать, но на самом деле это объект, встроенный в другие объекты.

Json:

{"restrictions": {
    "master": "bsu.school",
    "conditions": {
        "HCI": [
            "CMP",
            "HRM",
            "PUBL",
            "CRA",
            "FTV",
            "AGS",
            "MAS",
            "MCOM",
            "BMPP",
            "BUS",
            "CUS",
            "FSS",
            "PHET",
            "HIST",
            "ENL",
            "STR",
            "CWR",
            "STAF"
        ],
        "MPA": [
            "MAPE",
            "MAPS",
            "BACC",
            "MASW",
            "BAMU",
            "BAPA",
            "MAPA",
            "MATY",
            "MACM",
            "BADR",
            "KIST",
            "BADA",
            "PARM",
            "BAP",
            "BACM",
            "BATP",
            "MACO",
            "BACMT",
            "CSMT",
            "BAAM"
        ],
        "BSAD": [
            "BSAD3",
            "BSAD1",
            "BSAD2"
        ]
    }
}}

Я создал простой тестовый класспросто проверить синтаксический анализ этого конкретного объекта:

import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonParseTest {

    public static void main(String[] args) {
        String json = "{\"restrictions\":{\"master\":\"bsu.school\",\"conditions\":{\"HCI\":[\"CMP\",\"HRM\",\"PUBL\",\"CRA\",\"FTV\",\"AGS\",\"MAS\",\"MCOM\",\"BMPP\",\"BUS\",\"CUS\",\"FSS\",\"PHET\",\"HIST\",\"ENL\",\"STR\",\"CWR\",\"STAF\"],\"MPA\":[\"MAPE\",\"MAPS\",\"BACC\",\"MASW\",\"BAMU\",\"BAPA\",\"MAPA\",\"MATY\",\"MACM\",\"BADR\",\"KIST\",\"BADA\",\"PARM\",\"BAP\",\"BACM\",\"BATP\",\"MACO\",\"BACMT\",\"CSMT\",\"BAAM\"],\"BSAD\":[\"BSAD3\",\"BSAD1\",\"BSAD2\"]}}}";
        ObjectMapper objectMapper = new ObjectMapper();
        // Convert the json string to Restrictions object
        try {
            RestrictionsContainer restrictionsContainer = objectMapper.readValue(json, RestrictionsContainer.class);
            System.out.println("restrictionsContainer " + restrictionsContainer);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

RestrictionsContainer class:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class RestrictionsContainer {
    private Restrictions restrictions = null;

    /**
     * @return the restrictions
     */
    public Restrictions getRestrictions() {
        return restrictions;
    }

    /**
     * @param restrictions the restrictions to set
     */
    public void setRestrictions(Restrictions restrictions) {
        this.restrictions = restrictions;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("RestrictionsContainer [restrictions=").append(restrictions).append("]");
        return builder.toString();
    }
}

Ограничения класса:

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Restrictions {
    private String master = null;

    private Map<String, Object> conditions = new HashMap<>();

    /**
     * @return the master
     */
    public String getMaster() {
        return master;
    }

    /**
     * @param master the master to set
     */
    public void setMaster(String master) {
        this.master = master;
    }

    /**
     * @return the conditions
     */
    public Map<String, Object> getConditions() {
        return conditions;
    }

    /**
     * @param conditions the conditions to set
     */
    public void setConditions(Map<String, Object> conditions) {
        this.conditions = conditions;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Restrictions [master=").append(master).append(", conditions=").append(conditions).append("]");
        return builder.toString();
    }
}

Приведенный выше код работает, когда я устанавливаюУсловия для сопоставления String и Objects, но я действительно хочу указать, какой это тип объектов, который, на мой взгляд, должен быть:

private Map<String, Map<String,List<String>>> conditions = new HashMap<>();

Однако, когда я использую это вместо этого, я получаю следующее сообщение об ошибке:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_ARRAY token
 at [Source: (String)"{"restrictions":{"master":"bsu.school","conditions":{"HCI":["CMP","HRM","PUBL","CRA","FTV","AGS","MAS","MCOM","BMPP","BUS","CUS","FSS","PHET","HIST","ENL","STR","CWR","STAF"],"MPA":["MAPE","MAPS","BACC","MASW","BAMU","BAPA","MAPA","MATY","MACM","BADR","KIST","BADA","PARM","BAP","BACM","BATP","MACO","BACMT","CSMT","BAAM"],"BSAD":["BSAD3","BSAD1","BSAD2"]}}}"; line: 1, column: 60] (through reference chain: RestrictionsContainer["restrictions"]->Restrictions["conditions"]->java.util.LinkedHashMap["HCI"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1138)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1092)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromEmpty(StdDeserializer.java:599)....

Строковые ключи для объекта условий являются динамическими, поэтому я не могу использовать объект.

Как правильно определить объект условий?

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

В вашем коде нет ничего плохого, кроме неспособности Джексона "напрямую ссылаться на типы". Ссылка на тип Возвращает тип, представляющий прямой суперкласс сущности (класс, интерфейс, примитивный тип или void), представленный этим классом.

Если суперкласс является параметризованным типом, возвращаемый объект Type должен точно отражать фактические параметры типа, используемые в исходном коде.

Ваше исправление должно выглядеть примерно так:

Map<String, Map<String,List<String>>> myObjects = mapper.readValue(mapData , new TypeReference<Map<String, Map<String,List<String>>>(){});

0 голосов
/ 19 декабря 2018

Вы определяете тип conditions неправильно:

private Map<String, Map<String,List<String>>> conditions = new HashMap<>(); // WRONG

На самом деле тип conditions в вашем json:

private Map<String, List<String>> conditions;

Измените это, и ваш код работаетхорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...