2013-07-12 32 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