2014-10-11 55 views
0

我有一个JSON是类似以下内容:转换JSON为Java对象,提供错误的类型枚举

 

    [{"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)); 

东西是地图列表,每个地图将对应一件事。我遍历列表并从每个映射中检查'type'并实例化适当的对象。 例如:

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

现在我有一个枚举所有者。所以我这样做:

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

我确实得到清单。但是,当我确认是这样的:

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

我得到错误: '预计java.lang.OWNERS( “A”)却得到了java.lang.String中( “A”)'

,你可以看到业主的类型是List。 我错过了什么?我解析错误的方式?

+0

您使用的是哪种JSON API?如果有方法将字符串映射到枚举,请使用方法constructCollectionType检查类。枚举是一个Java概念,而不是JSON。 – 2014-10-11 00:58:34

回答

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

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注解告诉杰克逊的类型使用您选择的名称JSON属性indentify类。 JsonTypeName注释指定您的班级的名称。

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

0

使用Jackson注释不适合我。所以我使用了它认为是String的默认值。我这样做:

List owners =(ArrayList)map.get(“owners”);

而现在通过取相应的枚举的valueOf该字符串转换这对我的枚举:

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