Thanks Tatu for prompt response and suggestion.

I could solve the 1st issue by overriding withResolved() method and got 
CustomCollectionDeserializer working as described below. However, I see the 
complications it will bring in for maintaining this class. I will instead 
go with your suggested approach to do manipulation directly on JSON node 
and deserialize the merged object.

*public* *class* CustomCollectionDeserializer *extends* 
CollectionDeserializer {

    *public* CustomCollectionDeserializer(JavaType collectionType, 
JsonDeserializer<Object> valueDeser, TypeDeserializer valueTypeDeser, 
ValueInstantiator valueInstantiator) {

        *super*(collectionType, valueDeser, valueTypeDeser, 
valueInstantiator);

    }

    *protected* CustomCollectionDeserializer(JavaType collectionType, 
JsonDeserializer<Object> valueDeser, TypeDeserializer valueTypeDeser, 
ValueInstantiator valueInstantiator, JsonDeserializer<Object> 
delegateDeser, NullValueProvider nuller, Boolean unwrapSingle) {

        *super*(collectionType, valueDeser, valueTypeDeser, 
valueInstantiator, delegateDeser, nuller, unwrapSingle);

    }

    @Override

    *protected* CollectionDeserializer withResolved(JsonDeserializer<?> dd, 
JsonDeserializer<?> vd, TypeDeserializer vtd,

            NullValueProvider nuller, Boolean unwrapSingle) {

        *return* *new* CustomCollectionDeserializer(_containerType, 
(JsonDeserializer<Object>) vd, vtd, _valueInstantiator, 
(JsonDeserializer<Object>) dd, nuller, unwrapSingle);

    }

    @Override

    *public* Collection<Object> deserialize(JsonParser p, 
DeserializationContext ctxt, Collection<Object> intoValue)

            *throws* IOException {

        *return* *super*.deserialize(p, ctxt, intoValue);

    }

}
Regards,
Saurin


On Tuesday, April 6, 2021 at 4:33:14 PM UTC-7 Tatu Saloranta wrote:

> On Tue, Apr 6, 2021 at 4:28 PM Saurin Joshi <[email protected]> wrote:
> >
> > Apologies for opening a zombie thread. I am also interested in deep 
> merge of 2 arrays based on index.
> >
> > If I have 2 JSON strings JSON string1 and JSON string2 as below, then I 
> would like the output merged property like Merged JSON
> >
> > JSON string1:
> > {
> > "property1": [
> > {
> > "property2": "value1",
> > },
> > {
> > "property2": "value2",
> > }
> > ]
> > }
> >
> > JSON string2:
> > {
> > "property1": [
> > {
> > "property3": "value3"
> > },
> > {
> > "property3": "value4"
> > }
> > ]
> > }
> >
> > Merged JSON:
> > {
> > "property1": [
> > {
> > "property2": "value1",
> > "property3": "value3"
> > },
> > {
> > "property2": "value2",
> > "property3": "value4"
> > }
> > ]
> > }
> >
> > As one of the solutions, I tried registering custom deserializer (which 
> can look at array index position for merging) by extending 
> CollectionDeserializer like below. This code gets executed but the custom 
> deserializer doesn't get called while deserializing my class. Jackson still 
> calls CollectionDeserializer.
> >
> > private static void registerDeserializer(ObjectMapper mapper) {
> >
> > SimpleModule module = new SimpleModule();
> >
> > module.setDeserializerModifier(new BeanDeserializerModifier() {
> >
> > @Override
> >
> > public JsonDeserializer<?> 
> modifyCollectionDeserializer(DeserializationConfig config, CollectionType 
> type, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
> >
> > if (List.class.isAssignableFrom(beanDesc.getBeanClass()) && deserializer 
> instanceof CollectionDeserializer) {
> >
> > CollectionDeserializer collectionDeserializer = 
> (CollectionDeserializer)deserializer;
> >
> > if (LIST_CLASSES.stream().anyMatch(clazz -> 
> clazz.isAssignableFrom(type.getContentType().getRawClass()))) {
> >
> > return new CustomCollectionDeserializer(type, null, null, 
> collectionDeserializer.getValueInstantiator());
> >
> > }
> >
> > }
> >
> > return deserializer;
> >
> > }});
> >
> > mapper.registerModule(module);
> >
> > }
> >
> >
> > public static <T> T mergeObjects(T obj1, String obj2) throws 
> JsonMappingException, JsonProcessingException {
> >
> > ObjectReader objectReader = mapper.readerForUpdating(obj1);
> >
> > return objectReader.readValue(obj2);
> >
> > }
> >
> >
> > Can you help me with:
> > - how to register custom CollectionDeserializer, so that it gets 
> invoked? or
> > - suggest if there are better ways to achieve index based deep merge of 
> 2 arrays
>
> I would recommend against trying to implement or extend
> CollectionDeserializer. Getting that right requires a lot of work.
> There is no way to change definition of merging for Arrays currently
> and it seems unlikely there will be much support
> given that there seem to be multiple things users may want to and no
> obvious simple configuration options to cover options
> (or at least I have not been able to think of such).
>
> I think most users would read content as JsonNode and implement
> merging on those instances with relatively
> simple traversal: this allows you to use exact rules you want.
> You can then convert (mapper.treeToValue()) resulting tree into actual
> value type you want (and vice versa).
>
> -+ Tatu +-
>

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-user/0422e123-991b-4101-b615-ba489a0a27f2n%40googlegroups.com.

Reply via email to