如果一个字段的类型未知,如何解析杰克逊的JSON对象

时间:2014-09-05 16:01:50

标签: java json jackson

我有一个JSON响应,我尝试用Jackson解析,其中一个字段的类型未知。

Exapmle:

{"name" : "Catalina"}

OR

{"name" : {"First" : "Catalina", "Last" : "Kyle"}}

如何将该对象反序列化为POJO:

class NamesHolder {
    public String singleName;
    public Map<String, String> nameMap;
}

这是一个合成的例子,但我希望理解清楚。

在第一种情况下,我希望对象具有singleName ==“Catalina”和nameMap == null,反之亦然。

更新

我真的很抱歉,在一天结束时,我拼错了房产名称。在这两种情况下,它们都是相同的:名称。

2 个答案:

答案 0 :(得分:2)

尝试将您的名字字段设为对象:

class MyPojo {
  public Object name;
}

您必须在运行时检查它是否反序列化为String或Map。

答案 1 :(得分:0)

最简单的方法是将POJO属性重命名为JSON中的属性。见下面的例子:

class NamesHolder {
    public String name;
    public Map<String, String> names;

    @Override
    public String toString() {
        return "NamesHolder{" +
                "name='" + name + '\'' +
                ", names=" + names +
                '}';
    }
}

如果您不想重命名属性,可以使用@JsonProperty注释。见下面的例子:

class NamesHolder {

    @JsonProperty("name")
    public String singleName;

    @JsonProperty("names")
    public Map<String, String> nameMap;

    @Override
    public String toString() {
        return "NamesHolder{" +
                "name='" + singleName + '\'' +
                ", names=" + nameMap +
                '}';
    }
}

以上两个类适用于您的JSON示例。见下面的程序:

ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue("{\"names\" : {\"First\" : \"Catalina\", \"Last\" : \"Kyle\"}}", NamesHolder.class));
System.out.println(mapper.readValue("{\"name\" : \"Catalina\"}", NamesHolder.class));

打印:

NamesHolder{name='null', names={First=Catalina, Last=Kyle}}
NamesHolder{name='Catalina', names=null}

编辑1


在这种情况下,您必须使用Object类型手动处理它。见下面的例子:

public class JacksonTest {

    public static void main(String[] args) throws Exception {
        String json = "{\"name\" : \"Catalina\"}";
        ObjectMapper deserializerMapper = new ObjectMapper();
        NamesHolder namesHolder = deserializerMapper.readValue(json, NamesHolder.class);
        System.out.println(toString(namesHolder));

        json = "{\"name\" : {\"First\" : \"Catalina\", \"Last\" : \"Kyle\"}}";
        namesHolder = deserializerMapper.readValue(json, NamesHolder.class);
        System.out.println(toString(namesHolder));
    }

    private static String toString(NamesHolder namesHolder) {
        if (namesHolder.hasStringName()) {
            return "Type: String, Value: " + namesHolder.getStringName();
        } else if (namesHolder.hasMapNames()) {
            return "Type: Map, Value: " + namesHolder.getMapNames();
        }
        return "Type: Unknown, Value: " + namesHolder;
    }
}

class NamesHolder {

    public Object name;

    public boolean hasStringName() {
        return name instanceof String;
    }

    public String getStringName() {
        return name.toString();
    }

    public boolean hasMapNames() {
        return name instanceof Map;
    }

    public Map<String, String> getMapNames() {
        return (Map<String, String>) name;
    }

    @Override
    public String toString() {
        return String.valueOf(name);
    }
}

以上示例打印:

Type: String, Value: Catalina
Type: Map, Value: {First=Catalina, Last=Kyle}