2017-05-29 72 views
1

我有一個POJO類,如:JAXB序列化JsonElement場POJO

class Cat { 
    public Cat() {} 
    private String name; 
    private JsonElement arbitraryProperties; 
} 

我使用傑克遜(JAXB)和cat是一個資源我要導入和導出。

GET /cats/{id} 
POST /cats 

導出工作正常。導入不起作用,因爲JsonElement是抽象的。所以我將@JsonDeserialize(使用= MyJsonElementDeserialize.class)註釋添加到arbitraryProperties field

MyJsonElementDeserialize類的樣子:

public class JsonElementDeserialize extends JsonDeserializer<JsonElement> { 

public JsonElementDeserialize() { 
} 

@Override 
public JsonElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { 
    return new JsonObject(); // here I need to create my object later 
} 

}

當我現在請與有效載荷POST /貓:

{ 
    "name": "Mia", 
    "arbitraryProperties": { 
     "a": 3, 
     "b": [], 
     "c": { 
      "d": "race" 
     } 
    } 
} 

傑克遜返回錯誤代碼400:

無法識別的字段「a」 (Cat類),未標記爲可忽略的(1個已知屬性:「name」])。

我的錯誤在哪裏?我如何在我的POJO中有一個JsonElement自動序列化和反序列化?

+1

什麼是JsonElement?它是GSON的一部分嗎?所以爲什麼不使用它? –

+0

是JsonElement是來自GSON的抽象類。 https://google.github.io/gson/apidocs/com/google/gson/JsonElement.html – user1482309

+0

一個小的建議:標題說「序列化」,但問題是關於「反序列化」。改變標題會更有意義,更容易以這種方式找到相關問題。 – StaxMan

回答

4

下面是使用Cat setter方法改造的東西傑克遜解析(如Map<String, Object>)到GSON JsonElement類型的簡單解決方案:

void setArbitraryProperties(Map<String, Object> properties) { 
    arbitraryProperties = new Gson().toJsonTree(properties).getAsJsonObject(); 
} 

你可以,如果你可以」做類似的事情自定義解串器內在這裏使用setter。我發現setter/getters更容易與Jackson進行轉換。

請注意,Gson實例可用於將Map轉換爲JsonElement(實際上爲JsonObject)。 Docs for toJsonTree

既然你有一個在GSON中定義的類型的字段,因此你有GSON作爲依賴並且無情地需要GSON來創建這個字段,你可以考慮Sharon的建議並跳過Jackson並使用GSON進行反序列化。

+2

我認爲這是處理無法識別的字段的最好方法。甚至可以使用Map作爲字段類型而不是JsonElement。 –

0

如果您使用Spring mvc,請嘗試在控制器方法中使用「produce = MediaType.APPLICATION_JSON_VALUE」和@ResponseBody。

1

這裏的問題是,反序列化器必須消耗它們覆蓋的所有內容:也就是說,如果反序列化器不「讀取」將綁定的JSON內容(這裏的內容爲a),它們將留作進一步處理。

解決方案應該是簡單的,只需要調用

jsonParser.skipChildren(); 

deserialize方法,它會跳過當前輸入令牌,以及它的所有內容(如果它的JSON對象或陣列)。

另外,如果你想使用的內容,你可以使用

jsonParser.readValueAsTree(); 

,並有一些其他方便的方法。

1

如果可以,我會將JsonElement更改爲JsonNode,並使用Jackson的「樹模型」。