2013-07-12 31 views
2

我有這樣一個類:傑克遜延遲反序列化領域

public class DeserializedHeader 
    int typeToClassId; 
    Object obj 

我知道是基於typeToClassId,這是不幸的是僅在運行時知道什麼類型的對象obj的。

我想根據typeToClassId解析obj - 這裏最好的方法是什麼?註釋看起來好像已經出來了,基於ObjectMapper的東西看起來是正確的,但我很難弄清楚最好的方法是什麼。

沿東西線 類clazz中= lookUpClassBasedOnId(typeToClassId) objectMapper.readValue(OBJ,clazz所)

顯然,這不起作用,因爲obj是已經反序列化......但我能做到這一點不知何故,在2個步驟,也許與co​​nvertValue?

+0

這是非常臭的設計。爲什麼你的類型是'Object'?爲什麼只在運行時才知道? –

+0

您可以在運行時創建一個Map >嗎?我不確定你有什麼和你需要什麼。你能用JSON和POJO類創建一個簡單的例子嗎? –

+0

絕對同意代碼的味道 - 這是第三方服務,但是,我真的不能控制這一點。 - 基本上,解析typeToClassId字段後,我會知道obj字段中的對象類型。 – secureboot

回答

3

這真是一個複雜而痛苦的問題。我不知道任何複雜而優雅的解決方案,但我可以與您分享我開發的想法。我已經創建了示例程序,幫助我向您展示如何解決您的問題。一開始,我已經創建了兩個簡單的POJO類:

class Product { 

    private String name; 

     // getters/setters/toString 
} 

class Entity { 

    private long id; 

    // getters/setters/toString 
} 

例輸入JSON這些類可能看起來像這樣。對於Product類:

{ 
    "typeToClassId" : 33, 
    "obj" : { 
    "name" : "Computer" 
    } 
} 

Entity類:

{ 
    "typeToClassId" : 45, 
    "obj" : { 
    "id" : 10 
    } 
} 

,我們要使用的主要功能是 「局部串行化/反序列化」。爲此,我們將在ObjectMapper上啓用FAIL_ON_UNKNOWN_PROPERTIES功能。現在我們必須創建兩個類來定義typeToClassIdobj屬性。

class HeaderType { 

    private int typeToClassId; 

    public int getTypeToClassId() { 
     return typeToClassId; 
    } 

    public void setTypeToClassId(int typeToClassId) { 
     this.typeToClassId = typeToClassId; 
    } 

    @Override 
    public String toString() { 
     return "HeaderType [typeToClassId=" + typeToClassId + "]"; 
    } 
} 

class HeaderObject<T> { 

    private T obj; 

    public T getObj() { 
     return obj; 
    } 

    public void setObj(T obj) { 
     this.obj = obj; 
    } 

    @Override 
    public String toString() { 
     return "HeaderObject [obj=" + obj + "]"; 
    } 
} 

而且,最後的源代碼,可以解析JSON:

// Simple binding 
Map<Integer, Class<?>> classResolverMap = new HashMap<Integer, Class<?>>(); 
classResolverMap.put(33, Product.class); 
classResolverMap.put(45, Entity.class); 

ObjectMapper mapper = new ObjectMapper(); 
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 

String json = "{...}"; 

// Parse type 
HeaderType headerType = mapper.readValue(json, HeaderType.class); 
// Retrieve class by integer value 
Class<?> clazz = classResolverMap.get(headerType.getTypeToClassId()); 
// Create dynamic type 
JavaType type = mapper.getTypeFactory().constructParametricType(HeaderObject.class, clazz); 
// Parse object 
HeaderObject<?> headerObject = (HeaderObject<?>) mapper.readValue(json, type); 
// Get the object 
Object result = headerObject.getObj(); 

System.out.println(result); 

幫助鏈接:

  1. How To Convert Java Map To/From JSON (Jackson)
  2. java jackson parse object containing a generic type object