Reputation: 31
I'm having 2 classes: Class A which contains Class B. I need to unmarshall json to the Class A type - but I need Class A to have one set of Deserialization features and Class B to have a different set. Is it possible? What would be the best way doing that? Thx!
Upvotes: 2
Views: 2607
Reputation: 31
Eventually I solved it by defining my own deserializer for the inner type and inside defining new static ObjectMapper of its own to hold the needed configurations.
public ObjectMapper MyObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper
.setAnnotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()))
SimpleModule simpleModule = new SimpleModule("PostSurveyModule", Version.unknownVersion());
simpleModule.addDeserializer(MyInnerObject.class, new MyInnerObjectDeserializer());
objectMapper.registerModule(simpleModule);
return objectMapper;
}
public static class MyInnerObjectDeserializer extends JsonDeserializer<MyInnerObject> {
static ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper
.setVisibilityChecker(objectMapper.getDeserializationConfig().getDefaultVisibilityChecker()
.withGetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY));
objectMapper.addMixInAnnotations(MyInnerObject.class, MyInnerObjectMixin.class); //some mixin to add
}
@Override
public MyInnerObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
MyInnerObject myInnerObject = objectMapper.readValue(jp, MyInnerObject.class);
return myInnerObject;
}
}
Upvotes: 1
Reputation: 116472
Actually if you want to change SerializationFeature
or DeserializationFeature
on per-call basis, you do not want use methods in ObjectMapper
, but rather construct ObjectReader
and/or ObjectWriter
like so:
static final ObjectMapper mapper = ...; // only create once, acts as factor
// later on
byte[] json = mapper.writer(SerializationFeature.INDENT_OUTPUT)
.without(SerializationFeature. WRAP_EXCEPTIONS)
.writeValueAsBytes(value);
MyType result = mapper.readerFor(MyType.class)
.with(DeserializationFeature.UNWRAP_ROOT_VALUE)
// and more 'with' or 'without' calls
readValue(json);
Note that whereas construction of ObjectMapper
is expensive, and instance absolutely need to be reused, construction of ObjectReader
and ObjectWriter
are cheap and are meant to be done on per-read/-write basis. So while they can be reused (instances are fully thread-safe, immutable) there is not necessarily much need.
Upvotes: 2