On Tue, Apr 6, 2021 at 8:48 PM Saurin Joshi <[email protected]> wrote:
>
> 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.

Right: it is technically perfectly doable, it's just that sub-classing
 (and inheritance more generally) is a bit fragile,
and over time CollectionDeserializer constructors have and will be
changing when new configuration settings need
to be passed. Old versions are kept as per SemVer, where possible, but
there will be less testing to try to ensure that
things actually fully work as expected with new default/placeholder
values -- tests typically do not cover @Deprecated
methods, fields or constructors

This may be fine when you control the Jackson version in use and can
work around possible complications wrt upgrades.
But I like to mention it as a general suggestion.

Good luck!

-+ Tatu +-

>
> 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.

-- 
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/CAL4a10ge00%2BHm_Ydex75w%2BhAusO4dhRpJmLgwj7addqY7ZhYyQ%40mail.gmail.com.

Reply via email to