2011-10-05 37 views
0

我目前有一个Join对象,我正在尝试编写一个自定义解串器。我们存储数据库的关键,并在JSON对象的Java类的名字,那看起来是这样的:自定义Jackson解串器无法确定目标类

{ 
    "@class": "com.mysite.data.ExpertFor", 
    "id": "expert-for-1", 
    "leftId": "user-profile-1", 
    "leftType": "com.mysite.data.UserProfile", 
    "rightId": "hotel-1", 
    "rightType": "com.mysite.data.Hotel" 
} 

我们这样做,所以我们不必存储在数据库中的实际对象;相反,我们在反序列化时检索它。问题是我的自定义序列化程序无法在JSON流中看到@class元素 - 因此,在读取所有数据后,它无法正确实例化所需的对象。这里是我的解串器:

public Join deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { 
    Map<String, Object> values = new HashMap<String, Object>(); 

    // Loop through the JSON document and pull out all 
    // the values and put them into the map 
    JsonToken token = jp.nextToken(); 
    while (token != JsonToken.END_OBJECT) { 
     logger.info("Non-data field: [" + token + "], name is [" + jp.getCurrentName() + "], text is [" + jp.getText() + "]"); 
     if (token == JsonToken.VALUE_STRING) { 
      values.put(jp.getCurrentName(), jp.getText()); 
     } 
     token = jp.nextToken(); 
    }   
    // remainder of code omitted for brevity 
}  

现在,被写入日志的Log4J的线条显示所有我预计JSON的有关元素,除了@class元素

Data field: [VALUE_STRING], name is [id], text is [expert-for-1] 
Data field: [VALUE_STRING], name is [leftId], text is [user-profile-1] 
Data field: [VALUE_STRING], name is [rightId], text is [hotel-1] 
Data field: [VALUE_STRING], name is [leftType], text is [com.mysite.data.UserProfile] 
Data field: [VALUE_STRING], name is [rightType], text is [com.mysite.data.Hotel] 

我曾尝试加入@JsonTypeInfo注释上我的课,像

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") 

,但它似乎在代码中的元素是越来越“吞噬”,我不知道怎么弄在它。我需要这个,因为任何Join的后代都需要反序列化。以下是关于此类所在层次结构的一些其他信息:

添加@TypeInfo注释仅用于试图查看发生了什么。无论是否存在,我都会得到同样的行为。真奇怪的是,我们在需要自定义反序列化的其他类中使用了相同的基本功能,而那些看到@class就没问题。下面是这种层级结构:

@JsonAutoDetect(value = JsonMethod.NONE) 
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class") 
public abstract class TaggedObject implements Serializable { 
... 
} 

,然后我们有数据对象

public abstract class DataObject extends TaggedObject { 
... 
} 

,然后我们有我们的加入类:

@JsonSerialize(using = Join.Serializer.class) 
@JsonDeserialize(using = Join.Deserializer.class) 
public abstract class Join<L, R> extends DataObject { 
... 
} 

我会认为@JsonTypeInfo将继承来自TaggedObject,但这里没有看到,但是它被同一层次结构中的其他类所看到。

任何人有任何想法如何我可以抓住这个对象的类,所以我可以创建适当的对象?我在这里错过了什么?

回答

0

您不应该尝试手动处理@class AND将其声明为由@JsonTypeInfo处理 - 或者让Jackson完全处理它(它可以并且将要执行),或者删除证书并手动处理。

0

使用杰克逊树模型,下面的代码打印缺失@class

ObjectMapper mapper = new ObjectMapper(); 
JsonNode root = mapper.readTree(jsonString); 
Iterator<String> iterator = root.fieldNames(); 
while (iterator.hasNext()) { 
    String fieldName = iterator.next(); 
    String fieldValue = root.get(fieldName).asText(); 
    System.out.println("name is [" + fieldName + "], text is [" + fieldValue + "]"); 
} 

输出:

name is [@class], text is [com.mysite.data.ExpertFor] 
name is [id], text is [expert-for-1] 
name is [leftId], text is [user-profile-1] 
name is [leftType], text is [com.mysite.data.UserProfile] 
name is [rightId], text is [hotel-1] 
name is [rightType], text is [com.mysite.data.Hotel] 
+0

尽管此代码可以回答这个问题,提供了关于如何和/或为什么其他上下文解决问题会提高答案的长期价值。 – thewaywewere