Ar1982
Ar1982

Reputation: 31

Jackson objectMapper to use multiple configurations

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

Answers (2)

Ar1982
Ar1982

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

StaxMan
StaxMan

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

Related Questions