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.