杰克逊,针对特定字段名称的自定义反序列化

时间:2014-12-15 23:16:12

标签: java json jackson deserialization

我想知道是否可以根据字段名称自定义json的反序列化,例如

{
   id: "abc123",
   field1: {...}
   other: {
        field1: {....}
     }
}

我以前的json,我希望在json的任何级别为名为" field1"的字段设置自定义反序列化器。

原因:我们将数据保存为JSON,并且我们有一个返回此类数据的REST服务,但在返回之前,服务必须在" field1"中注入额外的信息。属性。

这些类型非常动态,因此我们无法定义Java类来映射json以使用注释。

第一种方法是反序列化为Map.class,然后使用JsonPath搜索$ .. field1模式,但这个过程对于更大的对象来说是昂贵的。

我感谢任何帮助。

谢谢,

埃德温·米格尔

2 个答案:

答案 0 :(得分:3)

为此,您应该考虑为ObjectMapper注册custom deserializer

然后,您应该能够简单地将JSON流映射到Map<String, Object>,因为您知道自定义代码将处理您的field1个对象。

答案 1 :(得分:1)

我创建了一个自定义反序列化器并将其添加到ObjectMapper的SimpleModule

public class CustomDeserializer extends StdDeserializer<Map> {
public CustomDeserializer() {
    super(Map.class);
}

@Override
public Map deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    Map<String, Object> result = new HashMap<String, Object>();
    jp.nextToken();
    while (!JsonToken.END_OBJECT.equals(jp.getCurrentToken())) {
        String key = jp.getText();
        jp.nextToken();
        if ("field1".equals(key)) {
            MyObject fiedlObj= jp.readValueAs(MyObject.class);
            //inject extra info
            //...
            result.put(key, fieldObj);
        } else {
            if (JsonToken.START_OBJECT.equals(jp.getCurrentToken())) {
                result.put(key, deserialize(jp, ctxt));
            } else if (JsonToken.START_ARRAY.equals(jp.getCurrentToken())) {
                jp.nextToken();
                List<Object> linkedList = new LinkedList<Object>();
                while (!JsonToken.END_ARRAY.equals(jp.getCurrentToken())) {
                    linkedList.add(deserialize(jp, ctxt));
                    jp.nextToken();
                }
                result.put(key, linkedList);
            } else {
                result.put(key, jp.readValueAs(Object.class));
            }
        }
        jp.nextToken();
    }
    return result;
}

}

问题是我必须为剩余的属性实现解析。

目前,这是我的解决方案......