我有一个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。 我错过了什么?我解析错误的方法吗?
答案 0 :(得分:0)
试试这个
assertEquals(OWNERS.A.toString(), owners.get(0));
此外,这一行
List<OWNERS> owners = (ArrayList<OWNERS>) map.get("owners");
在运行时因类型擦除而起作用。如果您尝试读取列表中的元素并将其转换为OWNERS(因为它实际上是一个字符串列表),它将崩溃。
答案 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));