使用Jackson库从JSON反序列化时,以自定义方式(而不是通过调用默认构造函数)实例化bean的最佳和最简单的方法是什么?我发现我可以实现JsonDeserializer
接口,但我不太确定如何将它们连接到ObjectMapper
。
更新#1 :我认为我的问题需要更多细节。默认情况下,Jackson的反序列化器使用默认构造函数来创建bean。我希望能够通过调用外部工厂来实现bean的实例化。所以我需要的只是一个需要实例化的bean类。工厂将返回实例,然后可以提供给杰克逊的财产人口等。
请注意,我并不关心创建简单/标量值(如字符串或数字),只有豆类属于我感兴趣的区域。
答案 0 :(得分:8)
有些事可能有帮助...
首先,您可以使用@JsonCreator来定义要使用的备用构造函数(所有参数都必须使用@JsonProperty注释,因为字节码没有名称)或静态工厂。它仍然是值类的一部分,但可以帮助支持不可变对象。
其次,如果您想要真正的自定义反序列化过程,可以查看http://wiki.fasterxml.com/JacksonHowToCustomDeserializers,它解释了如何注册自定义反序列化器。
杰克逊目前遗漏的一件事是对建筑风格的物品的支持;有一个功能请求可以添加支持(计划是在开发人员有时间的情况下在将来添加支持)。
答案 1 :(得分:0)
您将反序列化器放在要将json映射到的Java对象上:
@JsonDeserialize(using = PropertyValueDeserializer.class)
public class PROPERTY_VALUE implements Serializable{
然后在解串器中你可以例如做:
@Override
public PROPERTY_VALUE deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
String tmp = jsonParser.getText(); // {
jsonParser.nextToken();
String key = jsonParser.getText();
jsonParser.nextToken();
String value = jsonParser.getText();
jsonParser.nextToken();
tmp = jsonParser.getText(); // }
PROPERTY_VALUE pv = new PROPERTY_VALUE(key,value);
return pv;
}
如果您不想使用注释,则需要传递映射器DeserializerProvider
,它可以为给定类型提供正确的反序列化器。
mapper.setDeserializerProvider(myDeserializerProvider);
对于构造函数 - 当然你可以通过在反序列化器中调用工厂来生成目标类:
String value = jsonParser.getText();
jsonParser.nextToken();
tmp = jsonParser.getText(); // }
MyObject pv = MyObjectFactory.get(key);
pv.setValue(value);
return pv;
}
但是我可能误解了你的更新