将json转换为java对象,给出错误的枚举类型

时间:2014-10-11 00:38:09

标签: java json enums

我有一个json,如下所示:


    [{"type":"chair", "color":"red", "owners":["A","B"]},
    {"type":"vase", "shape":"oval", "owners":["B", "C"]}]

如图所示,两个条目都不同。所以我需要反序列化这个json并实例化2个对象Chair和Vase。上面的所有者应该是相应对象中的枚举列表。 json可以有许多其他不同的条目,如任何顺序。所以我这样做:

List<Map<String, Object>> things = objectMapper.readValue(json,
objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class));

事物是地图列表,每个地图都对应一件事。我遍历列表,并从每个地图检查&#39;键入&#39;并实例化适当的对象。 例如:

if map.get("type") == "chair" then new Chair(map.get("color"), map.get("owners"));

现在我有一个enum OWNERS。所以我这样做:

List<OWNERS> owners = (ArrayList<OWNERS>) map.get("owners");

我确实得到了清单。但是当我这样验证时:

assertEquals(OWNERS.A, owners.get(0));

我收到错误:&#39;期望java.lang.OWNERS(&#34; A&#34;)但是得到了java.lang.String(&#34; A&#34;)&#39;

正如您所看到的所有者类型是List。 我错过了什么?我解析错误的方法吗?

3 个答案:

答案 0 :(得分:0)

试试这个

assertEquals(OWNERS.A.toString(), owners.get(0));

此外,这一行

List<OWNERS> owners = (ArrayList<OWNERS>) map.get("owners");

在运行时因类型擦除而起作用。如果您尝试读取列表中的元素并将其转换为OWNERS(因为它实际上是一个字符串列表),它将崩溃。

检查Java generics - type erasure - when and what happens

答案 1 :(得分:0)

问题来自Map<String, Object>。您的对象映射器无法推断所有者的类型,需要猜测并假设它是String

您可以做的一件事是将字符串列表转换为所有者列表。

更好的解决方案是使用类似jackson-databind的内容并注释您的Chair和Vase类。 Jackson有注释,可以从JSON字段推断对象的类型(比如你的类型字段)。

您的代码应如下所示:

@JsonTypeName("chair")
@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="type")
public class Chair {
    @JsonCreator
    public Chair(@JsonProperty("color") String color, 
                 @JsonProperty("owners") List<OWNERS> owners) { }
}

JsonTypeInfo注释告诉jackson在类型JSON属性中使用您选择的名称来识别您的类。 JsonTypeName注释指定了您的类的名称。

如果您不想打扰注释,可以使用jackson's tree model。通过类似Map的界面加载json内容。

答案 2 :(得分:0)

使用杰克逊注释对我来说不是一个选择。所以我使用它认为是字符串的默认值。我这样做了:

List owners =(ArrayList)map.get(&#34; owner&#34;);

现在通过获取相应的枚举值valueOf将其转换为我的枚举:

OWNERS.valueOf(owners.get(0));