How to instantiate beans in custom way with Jackson?
What is the best and easiest way to instantiate beans in custom way (not by calling default constructor) while deserializing from JSON using Jackson library? I found that there is JsonDeserializer
interface that I could implement, but I'm not too sure how to wire it all together into the ObjectMapper
.
UPDATE #1: I think some more details is required for my question. By default Jackson's deserializer uses default constructor to crete beans. I'd like to be able to implement instantiation of the bean by calling external factory. So what I need is just a class of the bean that needs to be instantiated. The factory will return instance that can then be provided to Jackson for property population and so on.
Please note that I'm not concerned about creation of simple/scalar values such as s开发者_如何转开发trings or numbers, only the beans are in the area of my interest.
Some things that may help...
First, you can use @JsonCreator to define alternate constructor to use (all arguments must be annotated with @JsonProperty because bytecode has no names), or a static factory. It would still be part of value class, but can help support immutable objects.
Second, if you want truly custom deserialization process, you can check out https://github.com/FasterXML/jackson-docs/wiki/JacksonHowToCustomSerializers which explains how to register custom deserializers.
One thing that Jackson currently misses is support for builder-style objects; there is a feature request to add support (and plan is to add support in future once developers have time).
You put the deserializer on the Java object you want to get the json mapped into:
@JsonDeserialize(using = PropertyValueDeserializer.class)
public class PROPERTY_VALUE implements Serializable{
and then in the Deserializer you can e.g. do:
@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;
}
If you don't want to use annotations, you need to pass the mapper a DeserializerProvider
that can provide the right deserializer for a given type.
mapper.setDeserializerProvider(myDeserializerProvider);
For the constructors - of course you can generate the target class by calling a factory within the deserializer:
String value = jsonParser.getText();
jsonParser.nextToken();
tmp = jsonParser.getText(); // }
MyObject pv = MyObjectFactory.get(key);
pv.setValue(value);
return pv;
}
But then I may have misunderstood your update
精彩评论