2014-10-11 224 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));