简体   繁体   English

包含字符串映射的Java解析Json对象,以映射到字符串和字符串数组

[英]Java Parse Json Object Containing Map of Strings to Map to Strings to a String Array

I am trying to parse a json string that is an object that contains a map of string keys to a map of string keys to a string array. 我试图解析一个json字符串,它是一个对象,其中包含字符串键映射到字符串键映射到字符串数组。 I have simplified the json string to just the object that I am struggling to parse but is actually an object embedded within other objects. 我已经将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"
        ]
    }
}}

I have created a simple test class to just test parsing this particular object: 我创建了一个简单的测试类,仅用于测试分析此特定对象:

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();
    }
}

Restrictions class: 限制等级:

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();
    }
}

The code above works when I set the the Conditions to a map of String to Objects but what I really want is to specify what type of objects it is which I think should be: 上面的代码在将“条件”设置为“字符串到对象”的映射时有效,但是我真正想要的是指定我认为应该是什么类型的对象:

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

However, when I use this instead I get the following error message: 但是,当我改用它时,出现以下错误消息:

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)....

The string keys for the conditions object are dynamic so I can't use an object. 条件对象的字符串键是动态的,因此我不能使用对象。

What is the correct way to define the conditions object? 定义条件对象的正确方法是什么?

You are defining the type of conditions wrong: 您正在定义错误的conditions类型:

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

Actually the type of conditions in your json is: 实际上,您json中的conditions类型为:

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

Change this and your code works fine. 更改此设置,您的代码将正常运行。

There is nothing wrong with your code, but rather Jackson's inability to "directly reference types" .Type reference Returns the Type representing the direct superclass of the entity (class, interface, primitive type or void) represented by this Class. 您的代码没有错,但是Jackson不能“直接引用类型”。类型引用返回表示该类表示的实体的直接超类(类,接口,原始类型或void)的Type。

If the superclass is a parameterized type, the Type object returned must accurately reflect the actual type parameters used in the source code. 如果超类是参数化类型,则返回的Type对象必须准确反映源代码中使用的实际类型参数。

Your fix should be something like this: 您的修复应该是这样的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM