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/CAL4a10juws8e86wPZuSwkYkYUJjLvWq4DhfcWannuazLNsabLA%40mail.gmail.com.

Reply via email to